From a818710589924916fcb4981ff0ed531c94d4d832 Mon Sep 17 00:00:00 2001 From: goyuken Date: Sun, 15 Dec 2013 20:51:57 +0000 Subject: [PATCH] http://www.youtube.com/watch?v=V3w2saj52fI --- BizHawk.Client.EmuHawk/MainForm.cs | 7 +- .../BizHawk.Emulation.Cores.csproj | 2 + .../Consoles/Sega/gpgx/GPGX.cs | 280 + .../Consoles/Sega/gpgx/LibGPGX.cs | 27 + genplus-gx/HISTORY.txt | 1023 + genplus-gx/LICENSE.txt | 621 + genplus-gx/Makefile.gc | 148 + genplus-gx/Makefile.libretro | 235 + genplus-gx/Makefile.wii | 148 + genplus-gx/cinterface/cinterface.c | 175 + genplus-gx/core/cart_hw/areplay.c | 319 + genplus-gx/core/cart_hw/areplay.h | 52 + genplus-gx/core/cart_hw/eeprom_93c.c | 249 + genplus-gx/core/cart_hw/eeprom_93c.h | 72 + genplus-gx/core/cart_hw/eeprom_i2c.c | 621 + genplus-gx/core/cart_hw/eeprom_i2c.h | 45 + genplus-gx/core/cart_hw/eeprom_spi.c | 358 + genplus-gx/core/cart_hw/eeprom_spi.h | 47 + genplus-gx/core/cart_hw/ggenie.c | 283 + genplus-gx/core/cart_hw/ggenie.h | 51 + genplus-gx/core/cart_hw/md_cart.c | 1906 ++ genplus-gx/core/cart_hw/md_cart.h | 90 + genplus-gx/core/cart_hw/sms_cart.c | 1324 + genplus-gx/core/cart_hw/sms_cart.h | 56 + genplus-gx/core/cart_hw/sram.c | 221 + genplus-gx/core/cart_hw/sram.h | 63 + genplus-gx/core/cart_hw/svp/imageformat.txt | 68 + genplus-gx/core/cart_hw/svp/ssp16.c | 1333 + genplus-gx/core/cart_hw/svp/ssp16.h | 79 + genplus-gx/core/cart_hw/svp/svp.c | 49 + genplus-gx/core/cart_hw/svp/svp.h | 33 + genplus-gx/core/cart_hw/svp/svpdoc.txt | 524 + genplus-gx/core/cd_hw/cd_cart.c | 267 + genplus-gx/core/cd_hw/cd_cart.h | 51 + genplus-gx/core/cd_hw/cdc.c | 705 + genplus-gx/core/cd_hw/cdc.h | 71 + genplus-gx/core/cd_hw/cdd.c | 1740 ++ genplus-gx/core/cd_hw/cdd.h | 112 + genplus-gx/core/cd_hw/gfx.c | 729 + genplus-gx/core/cd_hw/gfx.h | 116 + genplus-gx/core/cd_hw/pcm.c | 442 + genplus-gx/core/cd_hw/pcm.h | 77 + genplus-gx/core/cd_hw/scd.c | 1673 + genplus-gx/core/cd_hw/scd.h | 90 + genplus-gx/core/genesis.c | 540 + genplus-gx/core/genesis.h | 77 + genplus-gx/core/hvc.h | 652 + genplus-gx/core/input_hw/activator.c | 134 + genplus-gx/core/input_hw/activator.h | 49 + genplus-gx/core/input_hw/gamepad.c | 241 + genplus-gx/core/input_hw/gamepad.h | 57 + genplus-gx/core/input_hw/input.c | 374 + genplus-gx/core/input_hw/input.h | 149 + genplus-gx/core/input_hw/lightgun.c | 265 + genplus-gx/core/input_hw/lightgun.h | 51 + genplus-gx/core/input_hw/mouse.c | 159 + genplus-gx/core/input_hw/mouse.h | 47 + genplus-gx/core/input_hw/paddle.c | 111 + genplus-gx/core/input_hw/paddle.h | 49 + genplus-gx/core/input_hw/sportspad.c | 134 + genplus-gx/core/input_hw/sportspad.h | 49 + genplus-gx/core/input_hw/teamplayer.c | 176 + genplus-gx/core/input_hw/teamplayer.h | 50 + genplus-gx/core/input_hw/terebi_oekaki.c | 77 + genplus-gx/core/input_hw/terebi_oekaki.h | 47 + genplus-gx/core/input_hw/xe_a1p.c | 182 + genplus-gx/core/input_hw/xe_a1p.h | 49 + genplus-gx/core/io_ctrl.c | 591 + genplus-gx/core/io_ctrl.h | 68 + genplus-gx/core/loadrom.c | 1136 + genplus-gx/core/loadrom.h | 75 + genplus-gx/core/m68k/m68k.h | 389 + genplus-gx/core/m68k/m68kconf.h | 93 + genplus-gx/core/m68k/m68kcpu.c | 385 + genplus-gx/core/m68k/m68kcpu.h | 1415 + genplus-gx/core/m68k/m68ki_cycles.h | 4099 +++ .../core/m68k/m68ki_instruction_jump_table.h | 8195 +++++ genplus-gx/core/m68k/m68kops.h | 25461 ++++++++++++++++ genplus-gx/core/m68k/readme.txt | 315 + genplus-gx/core/m68k/s68kconf.h | 93 + genplus-gx/core/m68k/s68kcpu.c | 349 + genplus-gx/core/m68k/s68ki_cycles.h | 4099 +++ genplus-gx/core/macros.h | 49 + genplus-gx/core/mem68k.c | 1281 + genplus-gx/core/mem68k.h | 77 + genplus-gx/core/membnk.c | 322 + genplus-gx/core/membnk.h | 58 + genplus-gx/core/memz80.c | 682 + genplus-gx/core/memz80.h | 60 + genplus-gx/core/ntsc/changes.txt | 96 + genplus-gx/core/ntsc/license.txt | 504 + genplus-gx/core/ntsc/md_ntsc.c | 143 + genplus-gx/core/ntsc/md_ntsc.h | 154 + genplus-gx/core/ntsc/md_ntsc_config.h | 31 + genplus-gx/core/ntsc/md_ntsc_impl.h | 439 + genplus-gx/core/ntsc/readme.txt | 58 + genplus-gx/core/ntsc/sms_ntsc.c | 141 + genplus-gx/core/ntsc/sms_ntsc.h | 154 + genplus-gx/core/ntsc/sms_ntsc.txt | 119 + genplus-gx/core/ntsc/sms_ntsc_config.h | 31 + genplus-gx/core/ntsc/sms_ntsc_impl.h | 439 + genplus-gx/core/shared.h | 35 + genplus-gx/core/sound/blip_buf.c | 405 + genplus-gx/core/sound/blip_buf.h | 74 + genplus-gx/core/sound/eq.c | 132 + genplus-gx/core/sound/eq.h | 67 + genplus-gx/core/sound/sn76489.c | 451 + genplus-gx/core/sound/sn76489.h | 23 + genplus-gx/core/sound/sound.c | 275 + genplus-gx/core/sound/sound.h | 53 + genplus-gx/core/sound/ym2413.c | 1721 ++ genplus-gx/core/sound/ym2413.h | 23 + genplus-gx/core/sound/ym2612.c | 2178 ++ genplus-gx/core/sound/ym2612.h | 28 + genplus-gx/core/state.c | 285 + genplus-gx/core/state.h | 57 + genplus-gx/core/system.c | 1384 + genplus-gx/core/system.h | 119 + genplus-gx/core/tremor/CHANGELOG | 19 + genplus-gx/core/tremor/COPYING | 28 + genplus-gx/core/tremor/README | 46 + genplus-gx/core/tremor/Version_script.in | 49 + genplus-gx/core/tremor/asm_arm.h | 243 + genplus-gx/core/tremor/backends.h | 130 + genplus-gx/core/tremor/bitwise.c | 265 + genplus-gx/core/tremor/block.c | 453 + genplus-gx/core/tremor/block.h | 24 + genplus-gx/core/tremor/codebook.c | 371 + genplus-gx/core/tremor/codebook.h | 102 + genplus-gx/core/tremor/codec_internal.h | 92 + genplus-gx/core/tremor/config_types.h | 25 + genplus-gx/core/tremor/configure.in | 131 + genplus-gx/core/tremor/floor0.c | 435 + genplus-gx/core/tremor/floor1.c | 441 + genplus-gx/core/tremor/framing.c | 1126 + genplus-gx/core/tremor/info.c | 356 + genplus-gx/core/tremor/ivorbiscodec.h | 202 + genplus-gx/core/tremor/ivorbisfile.h | 130 + genplus-gx/core/tremor/lsp_lookup.h | 136 + genplus-gx/core/tremor/mapping0.c | 306 + genplus-gx/core/tremor/mdct.c | 510 + genplus-gx/core/tremor/mdct.h | 52 + genplus-gx/core/tremor/mdct_lookup.h | 540 + genplus-gx/core/tremor/misc.h | 248 + genplus-gx/core/tremor/ogg.h | 206 + genplus-gx/core/tremor/os.h | 64 + genplus-gx/core/tremor/os_types.h | 42 + genplus-gx/core/tremor/registry.c | 50 + genplus-gx/core/tremor/registry.h | 40 + genplus-gx/core/tremor/res012.c | 342 + genplus-gx/core/tremor/sharedbook.c | 439 + genplus-gx/core/tremor/synthesis.c | 113 + genplus-gx/core/tremor/vorbisfile.c | 1597 + genplus-gx/core/tremor/window.c | 86 + genplus-gx/core/tremor/window.h | 27 + genplus-gx/core/tremor/window_lookup.h | 2084 ++ genplus-gx/core/types.h | 29 + genplus-gx/core/vdp_ctrl.c | 3259 ++ genplus-gx/core/vdp_ctrl.h | 105 + genplus-gx/core/vdp_render.c | 4206 +++ genplus-gx/core/vdp_render.h | 88 + genplus-gx/core/z80/osd_cpu.h | 47 + genplus-gx/core/z80/z80.c | 3457 +++ genplus-gx/core/z80/z80.h | 71 + genplus-gx/gx/config.c | 272 + genplus-gx/gx/config.h | 125 + genplus-gx/gx/fileio/file_load.c | 464 + genplus-gx/gx/fileio/file_load.h | 72 + genplus-gx/gx/fileio/file_slot.c | 830 + genplus-gx/gx/fileio/file_slot.h | 60 + genplus-gx/gx/fileio/fileio.c | 258 + genplus-gx/gx/fileio/fileio.h | 47 + genplus-gx/gx/fileio/history.c | 138 + genplus-gx/gx/fileio/history.h | 69 + genplus-gx/gx/gui/cheats.c | 1492 + genplus-gx/gx/gui/cheats.h | 50 + genplus-gx/gx/gui/filesel.c | 645 + genplus-gx/gx/gui/filesel.h | 58 + genplus-gx/gx/gui/font.c | 400 + genplus-gx/gx/gui/font.h | 49 + genplus-gx/gx/gui/gui.c | 1968 ++ genplus-gx/gx/gui/gui.h | 245 + genplus-gx/gx/gui/legal.c | 172 + genplus-gx/gx/gui/menu.c | 3683 +++ genplus-gx/gx/gui/menu.h | 46 + genplus-gx/gx/gui/saveicon.h | 136 + genplus-gx/gx/gx_audio.c | 210 + genplus-gx/gx/gx_audio.h | 52 + genplus-gx/gx/gx_input.c | 1641 + genplus-gx/gx/gx_input.h | 72 + genplus-gx/gx/gx_video.c | 2041 ++ genplus-gx/gx/gx_video.h | 105 + genplus-gx/gx/images/Banner_bottom.png | Bin 0 -> 4704 bytes genplus-gx/gx/images/Banner_main.png | Bin 0 -> 23123 bytes genplus-gx/gx/images/Banner_top.png | Bin 0 -> 6169 bytes genplus-gx/gx/images/Bg_credits.png | Bin 0 -> 291755 bytes genplus-gx/gx/images/Bg_intro_c1.png | Bin 0 -> 20755 bytes genplus-gx/gx/images/Bg_intro_c2.png | Bin 0 -> 17290 bytes genplus-gx/gx/images/Bg_intro_c3.png | Bin 0 -> 11446 bytes genplus-gx/gx/images/Bg_intro_c4.png | Bin 0 -> 10388 bytes genplus-gx/gx/images/Bg_layer.png | Bin 0 -> 260 bytes genplus-gx/gx/images/Bg_overlay.png | Bin 0 -> 212 bytes genplus-gx/gx/images/Browser_dir.png | Bin 0 -> 450 bytes genplus-gx/gx/images/Button_arrow.png | Bin 0 -> 3386 bytes genplus-gx/gx/images/Button_arrow_over.png | Bin 0 -> 3389 bytes genplus-gx/gx/images/Button_delete.png | Bin 0 -> 4433 bytes genplus-gx/gx/images/Button_delete_over.png | Bin 0 -> 4466 bytes genplus-gx/gx/images/Button_digit.png | Bin 0 -> 1758 bytes genplus-gx/gx/images/Button_digit_over.png | Bin 0 -> 2277 bytes genplus-gx/gx/images/Button_down.png | Bin 0 -> 4199 bytes genplus-gx/gx/images/Button_down_over.png | Bin 0 -> 4287 bytes genplus-gx/gx/images/Button_icon.png | Bin 0 -> 7741 bytes genplus-gx/gx/images/Button_icon_over.png | Bin 0 -> 7409 bytes genplus-gx/gx/images/Button_icon_sm.png | Bin 0 -> 4985 bytes genplus-gx/gx/images/Button_icon_sm_over.png | Bin 0 -> 4914 bytes genplus-gx/gx/images/Button_load.png | Bin 0 -> 4460 bytes genplus-gx/gx/images/Button_load_over.png | Bin 0 -> 4509 bytes genplus-gx/gx/images/Button_save.png | Bin 0 -> 4607 bytes genplus-gx/gx/images/Button_save_over.png | Bin 0 -> 4618 bytes genplus-gx/gx/images/Button_sm_blue.png | Bin 0 -> 2889 bytes genplus-gx/gx/images/Button_sm_grey.png | Bin 0 -> 2581 bytes genplus-gx/gx/images/Button_sm_yellow.png | Bin 0 -> 2838 bytes genplus-gx/gx/images/Button_special.png | Bin 0 -> 4759 bytes genplus-gx/gx/images/Button_special_over.png | Bin 0 -> 4806 bytes genplus-gx/gx/images/Button_text.png | Bin 0 -> 2779 bytes genplus-gx/gx/images/Button_text_over.png | Bin 0 -> 2855 bytes genplus-gx/gx/images/Button_up.png | Bin 0 -> 3898 bytes genplus-gx/gx/images/Button_up_over.png | Bin 0 -> 4136 bytes genplus-gx/gx/images/CD_access_off.png | Bin 0 -> 877 bytes genplus-gx/gx/images/CD_access_on.png | Bin 0 -> 1812 bytes genplus-gx/gx/images/CD_ready_off.png | Bin 0 -> 837 bytes genplus-gx/gx/images/CD_ready_on.png | Bin 0 -> 1858 bytes genplus-gx/gx/images/Cart_gg.png | Bin 0 -> 31114 bytes genplus-gx/gx/images/Cart_md.png | Bin 0 -> 23753 bytes genplus-gx/gx/images/Cart_ms.png | Bin 0 -> 23290 bytes genplus-gx/gx/images/Cart_sg.png | Bin 0 -> 34509 bytes genplus-gx/gx/images/Crosshair_p1.png | Bin 0 -> 1806 bytes genplus-gx/gx/images/Crosshair_p2.png | Bin 0 -> 1651 bytes genplus-gx/gx/images/Ctrl_4wayplay.png | Bin 0 -> 5570 bytes genplus-gx/gx/images/Ctrl_activator.png | Bin 0 -> 2602 bytes genplus-gx/gx/images/Ctrl_config.png | Bin 0 -> 635 bytes genplus-gx/gx/images/Ctrl_gamepad_md.png | Bin 0 -> 4938 bytes genplus-gx/gx/images/Ctrl_gamepad_ms.png | Bin 0 -> 4286 bytes genplus-gx/gx/images/Ctrl_justifiers.png | Bin 0 -> 4600 bytes genplus-gx/gx/images/Ctrl_lightphaser.png | Bin 0 -> 3890 bytes genplus-gx/gx/images/Ctrl_menacer.png | Bin 0 -> 4627 bytes genplus-gx/gx/images/Ctrl_mouse.png | Bin 0 -> 3853 bytes genplus-gx/gx/images/Ctrl_none.png | Bin 0 -> 2227 bytes genplus-gx/gx/images/Ctrl_pad3b.png | Bin 0 -> 1842 bytes genplus-gx/gx/images/Ctrl_pad6b.png | Bin 0 -> 1777 bytes genplus-gx/gx/images/Ctrl_paddle.png | Bin 0 -> 4795 bytes genplus-gx/gx/images/Ctrl_sportspad.png | Bin 0 -> 4924 bytes genplus-gx/gx/images/Ctrl_teamplayer.png | Bin 0 -> 5929 bytes genplus-gx/gx/images/Ctrl_xe_a1p.png | Bin 0 -> 4848 bytes genplus-gx/gx/images/Frame_s1.png | Bin 0 -> 6997 bytes genplus-gx/gx/images/Frame_s1_title.png | Bin 0 -> 3510 bytes genplus-gx/gx/images/Frame_s2.png | Bin 0 -> 3890 bytes genplus-gx/gx/images/Frame_s2_title.png | Bin 0 -> 2285 bytes genplus-gx/gx/images/Frame_s3.png | Bin 0 -> 4447 bytes genplus-gx/gx/images/Frame_throbber.png | Bin 0 -> 2334 bytes genplus-gx/gx/images/Key_A_gcn.png | Bin 0 -> 1705 bytes genplus-gx/gx/images/Key_A_wii.png | Bin 0 -> 1542 bytes genplus-gx/gx/images/Key_B_gcn.png | Bin 0 -> 1633 bytes genplus-gx/gx/images/Key_B_wii.png | Bin 0 -> 1610 bytes genplus-gx/gx/images/Key_DPAD.png | Bin 0 -> 1189 bytes genplus-gx/gx/images/Key_L_gcn.png | Bin 0 -> 1850 bytes genplus-gx/gx/images/Key_Minus_wii.png | Bin 0 -> 1241 bytes genplus-gx/gx/images/Key_Plus_wii.png | Bin 0 -> 1346 bytes genplus-gx/gx/images/Key_R_gcn.png | Bin 0 -> 2105 bytes genplus-gx/gx/images/Load_cd.png | Bin 0 -> 5193 bytes genplus-gx/gx/images/Load_gg.png | Bin 0 -> 6452 bytes genplus-gx/gx/images/Load_md.png | Bin 0 -> 6767 bytes genplus-gx/gx/images/Load_ms.png | Bin 0 -> 6537 bytes genplus-gx/gx/images/Load_recent.png | Bin 0 -> 5676 bytes genplus-gx/gx/images/Load_sg.png | Bin 0 -> 5378 bytes genplus-gx/gx/images/Main_cheats.png | Bin 0 -> 2122 bytes genplus-gx/gx/images/Main_file.png | Bin 0 -> 8028 bytes genplus-gx/gx/images/Main_load.png | Bin 0 -> 11581 bytes genplus-gx/gx/images/Main_logo.png | Bin 0 -> 22305 bytes genplus-gx/gx/images/Main_options.png | Bin 0 -> 7506 bytes genplus-gx/gx/images/Main_play_gcn.png | Bin 0 -> 3732 bytes genplus-gx/gx/images/Main_play_wii.png | Bin 0 -> 3658 bytes genplus-gx/gx/images/Main_quit.png | Bin 0 -> 2242 bytes genplus-gx/gx/images/Main_reset.png | Bin 0 -> 6399 bytes genplus-gx/gx/images/Main_showinfo.png | Bin 0 -> 3694 bytes genplus-gx/gx/images/Main_takeshot.png | Bin 0 -> 3544 bytes genplus-gx/gx/images/Option_ctrl.png | Bin 0 -> 12311 bytes genplus-gx/gx/images/Option_menu.png | Bin 0 -> 2482 bytes genplus-gx/gx/images/Option_sound.png | Bin 0 -> 4305 bytes genplus-gx/gx/images/Option_system.png | Bin 0 -> 9709 bytes genplus-gx/gx/images/Option_video.png | Bin 0 -> 5072 bytes genplus-gx/gx/images/Overlay_bar.png | Bin 0 -> 2309 bytes genplus-gx/gx/images/Snap_empty.png | Bin 0 -> 27671 bytes genplus-gx/gx/images/Star_empty.png | Bin 0 -> 812 bytes genplus-gx/gx/images/Star_full.png | Bin 0 -> 994 bytes genplus-gx/gx/images/ctrl_classic.png | Bin 0 -> 1270 bytes genplus-gx/gx/images/ctrl_gamecube.png | Bin 0 -> 1310 bytes genplus-gx/gx/images/ctrl_nunchuk.png | Bin 0 -> 1329 bytes genplus-gx/gx/images/ctrl_option_off.png | Bin 0 -> 1004 bytes genplus-gx/gx/images/ctrl_option_on.png | Bin 0 -> 880 bytes genplus-gx/gx/images/ctrl_wiimote.png | Bin 0 -> 698 bytes genplus-gx/gx/images/generic_point.png | Bin 0 -> 2200 bytes genplus-gx/gx/main.c | 614 + genplus-gx/gx/osd.h | 86 + genplus-gx/gx/sounds/button_over.pcm | Bin 0 -> 160 bytes genplus-gx/gx/sounds/button_select.pcm | Bin 0 -> 11904 bytes genplus-gx/gx/sounds/intro.pcm | Bin 0 -> 56186 bytes genplus-gx/gx/utils/oggplayer.c | 536 + genplus-gx/gx/utils/oggplayer.h | 179 + genplus-gx/gx/utils/vi_encoder.c | 565 + genplus-gx/gx/utils/vi_encoder.h | 79 + genplus-gx/libretro/jni/Android.mk | 78 + genplus-gx/libretro/jni/Application.mk | 1 + genplus-gx/libretro/libretro.c | 1005 + genplus-gx/libretro/libretro.h | 758 + genplus-gx/libretro/link.T | 5 + genplus-gx/libretro/msvc/msvc-2003-xbox1.bat | 47 + genplus-gx/libretro/msvc/msvc-2003-xbox1.sln | 30 + .../msvc-2003-xbox1/msvc-2003-xbox1.vcproj | 543 + .../libretro/msvc/msvc-2003-xbox1/stdint.h | 249 + genplus-gx/libretro/msvc/msvc-2010-360.bat | 124 + genplus-gx/libretro/msvc/msvc-2010-360.sln | 38 + .../msvc/msvc-2010-360/msvc-2010-360.vcxproj | 373 + .../msvc-2010-360.vcxproj.filters | 186 + genplus-gx/libretro/msvc/msvc-2010.sln | 20 + .../libretro/msvc/msvc-2010/libretro.def | 27 + .../libretro/msvc/msvc-2010/msvc-2010.vcxproj | 145 + .../msvc/msvc-2010/msvc-2010.vcxproj.filters | 196 + genplus-gx/libretro/osd.h | 84 + genplus-gx/libretro/qnx/playbook/.cproject | 142 + genplus-gx/libretro/qnx/playbook/.project | 85 + genplus-gx/libretro/scrc32.c | 79 + genplus-gx/libretro/scrc32.h | 6 + genplus-gx/sdl/CHANGELOG.txt | 694 + genplus-gx/sdl/LICENSE.txt | 585 + genplus-gx/sdl/Makefile.sdl | 173 + genplus-gx/sdl/README.txt | 146 + genplus-gx/sdl/config.c | 52 + genplus-gx/sdl/config.h | 53 + genplus-gx/sdl/error.c | 35 + genplus-gx/sdl/error.h | 10 + genplus-gx/sdl/fileio.c | 158 + genplus-gx/sdl/fileio.h | 48 + genplus-gx/sdl/icon.rc | 1 + genplus-gx/sdl/main.c | 934 + genplus-gx/sdl/main.h | 11 + genplus-gx/sdl/md.ico | Bin 0 -> 42126 bytes genplus-gx/sdl/osd.h | 35 + genplus-gx/sdl/readme-sdl.txt | 5 + genplus-gx/sdl/unzip.c | 1294 + genplus-gx/sdl/unzip.h | 273 + output/dll/libgenplusgx.dll | Bin 0 -> 2545152 bytes 352 files changed, 128209 insertions(+), 2 deletions(-) create mode 100644 BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs create mode 100644 BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs create mode 100644 genplus-gx/HISTORY.txt create mode 100644 genplus-gx/LICENSE.txt create mode 100644 genplus-gx/Makefile.gc create mode 100644 genplus-gx/Makefile.libretro create mode 100644 genplus-gx/Makefile.wii create mode 100644 genplus-gx/cinterface/cinterface.c create mode 100644 genplus-gx/core/cart_hw/areplay.c create mode 100644 genplus-gx/core/cart_hw/areplay.h create mode 100644 genplus-gx/core/cart_hw/eeprom_93c.c create mode 100644 genplus-gx/core/cart_hw/eeprom_93c.h create mode 100644 genplus-gx/core/cart_hw/eeprom_i2c.c create mode 100644 genplus-gx/core/cart_hw/eeprom_i2c.h create mode 100644 genplus-gx/core/cart_hw/eeprom_spi.c create mode 100644 genplus-gx/core/cart_hw/eeprom_spi.h create mode 100644 genplus-gx/core/cart_hw/ggenie.c create mode 100644 genplus-gx/core/cart_hw/ggenie.h create mode 100644 genplus-gx/core/cart_hw/md_cart.c create mode 100644 genplus-gx/core/cart_hw/md_cart.h create mode 100644 genplus-gx/core/cart_hw/sms_cart.c create mode 100644 genplus-gx/core/cart_hw/sms_cart.h create mode 100644 genplus-gx/core/cart_hw/sram.c create mode 100644 genplus-gx/core/cart_hw/sram.h create mode 100644 genplus-gx/core/cart_hw/svp/imageformat.txt create mode 100644 genplus-gx/core/cart_hw/svp/ssp16.c create mode 100644 genplus-gx/core/cart_hw/svp/ssp16.h create mode 100644 genplus-gx/core/cart_hw/svp/svp.c create mode 100644 genplus-gx/core/cart_hw/svp/svp.h create mode 100644 genplus-gx/core/cart_hw/svp/svpdoc.txt create mode 100644 genplus-gx/core/cd_hw/cd_cart.c create mode 100644 genplus-gx/core/cd_hw/cd_cart.h create mode 100644 genplus-gx/core/cd_hw/cdc.c create mode 100644 genplus-gx/core/cd_hw/cdc.h create mode 100644 genplus-gx/core/cd_hw/cdd.c create mode 100644 genplus-gx/core/cd_hw/cdd.h create mode 100644 genplus-gx/core/cd_hw/gfx.c create mode 100644 genplus-gx/core/cd_hw/gfx.h create mode 100644 genplus-gx/core/cd_hw/pcm.c create mode 100644 genplus-gx/core/cd_hw/pcm.h create mode 100644 genplus-gx/core/cd_hw/scd.c create mode 100644 genplus-gx/core/cd_hw/scd.h create mode 100644 genplus-gx/core/genesis.c create mode 100644 genplus-gx/core/genesis.h create mode 100644 genplus-gx/core/hvc.h create mode 100644 genplus-gx/core/input_hw/activator.c create mode 100644 genplus-gx/core/input_hw/activator.h create mode 100644 genplus-gx/core/input_hw/gamepad.c create mode 100644 genplus-gx/core/input_hw/gamepad.h create mode 100644 genplus-gx/core/input_hw/input.c create mode 100644 genplus-gx/core/input_hw/input.h create mode 100644 genplus-gx/core/input_hw/lightgun.c create mode 100644 genplus-gx/core/input_hw/lightgun.h create mode 100644 genplus-gx/core/input_hw/mouse.c create mode 100644 genplus-gx/core/input_hw/mouse.h create mode 100644 genplus-gx/core/input_hw/paddle.c create mode 100644 genplus-gx/core/input_hw/paddle.h create mode 100644 genplus-gx/core/input_hw/sportspad.c create mode 100644 genplus-gx/core/input_hw/sportspad.h create mode 100644 genplus-gx/core/input_hw/teamplayer.c create mode 100644 genplus-gx/core/input_hw/teamplayer.h create mode 100644 genplus-gx/core/input_hw/terebi_oekaki.c create mode 100644 genplus-gx/core/input_hw/terebi_oekaki.h create mode 100644 genplus-gx/core/input_hw/xe_a1p.c create mode 100644 genplus-gx/core/input_hw/xe_a1p.h create mode 100644 genplus-gx/core/io_ctrl.c create mode 100644 genplus-gx/core/io_ctrl.h create mode 100644 genplus-gx/core/loadrom.c create mode 100644 genplus-gx/core/loadrom.h create mode 100644 genplus-gx/core/m68k/m68k.h create mode 100644 genplus-gx/core/m68k/m68kconf.h create mode 100644 genplus-gx/core/m68k/m68kcpu.c create mode 100644 genplus-gx/core/m68k/m68kcpu.h create mode 100644 genplus-gx/core/m68k/m68ki_cycles.h create mode 100644 genplus-gx/core/m68k/m68ki_instruction_jump_table.h create mode 100644 genplus-gx/core/m68k/m68kops.h create mode 100644 genplus-gx/core/m68k/readme.txt create mode 100644 genplus-gx/core/m68k/s68kconf.h create mode 100644 genplus-gx/core/m68k/s68kcpu.c create mode 100644 genplus-gx/core/m68k/s68ki_cycles.h create mode 100644 genplus-gx/core/macros.h create mode 100644 genplus-gx/core/mem68k.c create mode 100644 genplus-gx/core/mem68k.h create mode 100644 genplus-gx/core/membnk.c create mode 100644 genplus-gx/core/membnk.h create mode 100644 genplus-gx/core/memz80.c create mode 100644 genplus-gx/core/memz80.h create mode 100644 genplus-gx/core/ntsc/changes.txt create mode 100644 genplus-gx/core/ntsc/license.txt create mode 100644 genplus-gx/core/ntsc/md_ntsc.c create mode 100644 genplus-gx/core/ntsc/md_ntsc.h create mode 100644 genplus-gx/core/ntsc/md_ntsc_config.h create mode 100644 genplus-gx/core/ntsc/md_ntsc_impl.h create mode 100644 genplus-gx/core/ntsc/readme.txt create mode 100644 genplus-gx/core/ntsc/sms_ntsc.c create mode 100644 genplus-gx/core/ntsc/sms_ntsc.h create mode 100644 genplus-gx/core/ntsc/sms_ntsc.txt create mode 100644 genplus-gx/core/ntsc/sms_ntsc_config.h create mode 100644 genplus-gx/core/ntsc/sms_ntsc_impl.h create mode 100644 genplus-gx/core/shared.h create mode 100644 genplus-gx/core/sound/blip_buf.c create mode 100644 genplus-gx/core/sound/blip_buf.h create mode 100644 genplus-gx/core/sound/eq.c create mode 100644 genplus-gx/core/sound/eq.h create mode 100644 genplus-gx/core/sound/sn76489.c create mode 100644 genplus-gx/core/sound/sn76489.h create mode 100644 genplus-gx/core/sound/sound.c create mode 100644 genplus-gx/core/sound/sound.h create mode 100644 genplus-gx/core/sound/ym2413.c create mode 100644 genplus-gx/core/sound/ym2413.h create mode 100644 genplus-gx/core/sound/ym2612.c create mode 100644 genplus-gx/core/sound/ym2612.h create mode 100644 genplus-gx/core/state.c create mode 100644 genplus-gx/core/state.h create mode 100644 genplus-gx/core/system.c create mode 100644 genplus-gx/core/system.h create mode 100644 genplus-gx/core/tremor/CHANGELOG create mode 100644 genplus-gx/core/tremor/COPYING create mode 100644 genplus-gx/core/tremor/README create mode 100644 genplus-gx/core/tremor/Version_script.in create mode 100644 genplus-gx/core/tremor/asm_arm.h create mode 100644 genplus-gx/core/tremor/backends.h create mode 100644 genplus-gx/core/tremor/bitwise.c create mode 100644 genplus-gx/core/tremor/block.c create mode 100644 genplus-gx/core/tremor/block.h create mode 100644 genplus-gx/core/tremor/codebook.c create mode 100644 genplus-gx/core/tremor/codebook.h create mode 100644 genplus-gx/core/tremor/codec_internal.h create mode 100644 genplus-gx/core/tremor/config_types.h create mode 100644 genplus-gx/core/tremor/configure.in create mode 100644 genplus-gx/core/tremor/floor0.c create mode 100644 genplus-gx/core/tremor/floor1.c create mode 100644 genplus-gx/core/tremor/framing.c create mode 100644 genplus-gx/core/tremor/info.c create mode 100644 genplus-gx/core/tremor/ivorbiscodec.h create mode 100644 genplus-gx/core/tremor/ivorbisfile.h create mode 100644 genplus-gx/core/tremor/lsp_lookup.h create mode 100644 genplus-gx/core/tremor/mapping0.c create mode 100644 genplus-gx/core/tremor/mdct.c create mode 100644 genplus-gx/core/tremor/mdct.h create mode 100644 genplus-gx/core/tremor/mdct_lookup.h create mode 100644 genplus-gx/core/tremor/misc.h create mode 100644 genplus-gx/core/tremor/ogg.h create mode 100644 genplus-gx/core/tremor/os.h create mode 100644 genplus-gx/core/tremor/os_types.h create mode 100644 genplus-gx/core/tremor/registry.c create mode 100644 genplus-gx/core/tremor/registry.h create mode 100644 genplus-gx/core/tremor/res012.c create mode 100644 genplus-gx/core/tremor/sharedbook.c create mode 100644 genplus-gx/core/tremor/synthesis.c create mode 100644 genplus-gx/core/tremor/vorbisfile.c create mode 100644 genplus-gx/core/tremor/window.c create mode 100644 genplus-gx/core/tremor/window.h create mode 100644 genplus-gx/core/tremor/window_lookup.h create mode 100644 genplus-gx/core/types.h create mode 100644 genplus-gx/core/vdp_ctrl.c create mode 100644 genplus-gx/core/vdp_ctrl.h create mode 100644 genplus-gx/core/vdp_render.c create mode 100644 genplus-gx/core/vdp_render.h create mode 100644 genplus-gx/core/z80/osd_cpu.h create mode 100644 genplus-gx/core/z80/z80.c create mode 100644 genplus-gx/core/z80/z80.h create mode 100644 genplus-gx/gx/config.c create mode 100644 genplus-gx/gx/config.h create mode 100644 genplus-gx/gx/fileio/file_load.c create mode 100644 genplus-gx/gx/fileio/file_load.h create mode 100644 genplus-gx/gx/fileio/file_slot.c create mode 100644 genplus-gx/gx/fileio/file_slot.h create mode 100644 genplus-gx/gx/fileio/fileio.c create mode 100644 genplus-gx/gx/fileio/fileio.h create mode 100644 genplus-gx/gx/fileio/history.c create mode 100644 genplus-gx/gx/fileio/history.h create mode 100644 genplus-gx/gx/gui/cheats.c create mode 100644 genplus-gx/gx/gui/cheats.h create mode 100644 genplus-gx/gx/gui/filesel.c create mode 100644 genplus-gx/gx/gui/filesel.h create mode 100644 genplus-gx/gx/gui/font.c create mode 100644 genplus-gx/gx/gui/font.h create mode 100644 genplus-gx/gx/gui/gui.c create mode 100644 genplus-gx/gx/gui/gui.h create mode 100644 genplus-gx/gx/gui/legal.c create mode 100644 genplus-gx/gx/gui/menu.c create mode 100644 genplus-gx/gx/gui/menu.h create mode 100644 genplus-gx/gx/gui/saveicon.h create mode 100644 genplus-gx/gx/gx_audio.c create mode 100644 genplus-gx/gx/gx_audio.h create mode 100644 genplus-gx/gx/gx_input.c create mode 100644 genplus-gx/gx/gx_input.h create mode 100644 genplus-gx/gx/gx_video.c create mode 100644 genplus-gx/gx/gx_video.h create mode 100644 genplus-gx/gx/images/Banner_bottom.png create mode 100644 genplus-gx/gx/images/Banner_main.png create mode 100644 genplus-gx/gx/images/Banner_top.png create mode 100644 genplus-gx/gx/images/Bg_credits.png create mode 100644 genplus-gx/gx/images/Bg_intro_c1.png create mode 100644 genplus-gx/gx/images/Bg_intro_c2.png create mode 100644 genplus-gx/gx/images/Bg_intro_c3.png create mode 100644 genplus-gx/gx/images/Bg_intro_c4.png create mode 100644 genplus-gx/gx/images/Bg_layer.png create mode 100644 genplus-gx/gx/images/Bg_overlay.png create mode 100644 genplus-gx/gx/images/Browser_dir.png create mode 100644 genplus-gx/gx/images/Button_arrow.png create mode 100644 genplus-gx/gx/images/Button_arrow_over.png create mode 100644 genplus-gx/gx/images/Button_delete.png create mode 100644 genplus-gx/gx/images/Button_delete_over.png create mode 100644 genplus-gx/gx/images/Button_digit.png create mode 100644 genplus-gx/gx/images/Button_digit_over.png create mode 100644 genplus-gx/gx/images/Button_down.png create mode 100644 genplus-gx/gx/images/Button_down_over.png create mode 100644 genplus-gx/gx/images/Button_icon.png create mode 100644 genplus-gx/gx/images/Button_icon_over.png create mode 100644 genplus-gx/gx/images/Button_icon_sm.png create mode 100644 genplus-gx/gx/images/Button_icon_sm_over.png create mode 100644 genplus-gx/gx/images/Button_load.png create mode 100644 genplus-gx/gx/images/Button_load_over.png create mode 100644 genplus-gx/gx/images/Button_save.png create mode 100644 genplus-gx/gx/images/Button_save_over.png create mode 100644 genplus-gx/gx/images/Button_sm_blue.png create mode 100644 genplus-gx/gx/images/Button_sm_grey.png create mode 100644 genplus-gx/gx/images/Button_sm_yellow.png create mode 100644 genplus-gx/gx/images/Button_special.png create mode 100644 genplus-gx/gx/images/Button_special_over.png create mode 100644 genplus-gx/gx/images/Button_text.png create mode 100644 genplus-gx/gx/images/Button_text_over.png create mode 100644 genplus-gx/gx/images/Button_up.png create mode 100644 genplus-gx/gx/images/Button_up_over.png create mode 100644 genplus-gx/gx/images/CD_access_off.png create mode 100644 genplus-gx/gx/images/CD_access_on.png create mode 100644 genplus-gx/gx/images/CD_ready_off.png create mode 100644 genplus-gx/gx/images/CD_ready_on.png create mode 100644 genplus-gx/gx/images/Cart_gg.png create mode 100644 genplus-gx/gx/images/Cart_md.png create mode 100644 genplus-gx/gx/images/Cart_ms.png create mode 100644 genplus-gx/gx/images/Cart_sg.png create mode 100644 genplus-gx/gx/images/Crosshair_p1.png create mode 100644 genplus-gx/gx/images/Crosshair_p2.png create mode 100644 genplus-gx/gx/images/Ctrl_4wayplay.png create mode 100644 genplus-gx/gx/images/Ctrl_activator.png create mode 100644 genplus-gx/gx/images/Ctrl_config.png create mode 100644 genplus-gx/gx/images/Ctrl_gamepad_md.png create mode 100644 genplus-gx/gx/images/Ctrl_gamepad_ms.png create mode 100644 genplus-gx/gx/images/Ctrl_justifiers.png create mode 100644 genplus-gx/gx/images/Ctrl_lightphaser.png create mode 100644 genplus-gx/gx/images/Ctrl_menacer.png create mode 100644 genplus-gx/gx/images/Ctrl_mouse.png create mode 100644 genplus-gx/gx/images/Ctrl_none.png create mode 100644 genplus-gx/gx/images/Ctrl_pad3b.png create mode 100644 genplus-gx/gx/images/Ctrl_pad6b.png create mode 100644 genplus-gx/gx/images/Ctrl_paddle.png create mode 100644 genplus-gx/gx/images/Ctrl_sportspad.png create mode 100644 genplus-gx/gx/images/Ctrl_teamplayer.png create mode 100644 genplus-gx/gx/images/Ctrl_xe_a1p.png create mode 100644 genplus-gx/gx/images/Frame_s1.png create mode 100644 genplus-gx/gx/images/Frame_s1_title.png create mode 100644 genplus-gx/gx/images/Frame_s2.png create mode 100644 genplus-gx/gx/images/Frame_s2_title.png create mode 100644 genplus-gx/gx/images/Frame_s3.png create mode 100644 genplus-gx/gx/images/Frame_throbber.png create mode 100644 genplus-gx/gx/images/Key_A_gcn.png create mode 100644 genplus-gx/gx/images/Key_A_wii.png create mode 100644 genplus-gx/gx/images/Key_B_gcn.png create mode 100644 genplus-gx/gx/images/Key_B_wii.png create mode 100644 genplus-gx/gx/images/Key_DPAD.png create mode 100644 genplus-gx/gx/images/Key_L_gcn.png create mode 100644 genplus-gx/gx/images/Key_Minus_wii.png create mode 100644 genplus-gx/gx/images/Key_Plus_wii.png create mode 100644 genplus-gx/gx/images/Key_R_gcn.png create mode 100644 genplus-gx/gx/images/Load_cd.png create mode 100644 genplus-gx/gx/images/Load_gg.png create mode 100644 genplus-gx/gx/images/Load_md.png create mode 100644 genplus-gx/gx/images/Load_ms.png create mode 100644 genplus-gx/gx/images/Load_recent.png create mode 100644 genplus-gx/gx/images/Load_sg.png create mode 100644 genplus-gx/gx/images/Main_cheats.png create mode 100644 genplus-gx/gx/images/Main_file.png create mode 100644 genplus-gx/gx/images/Main_load.png create mode 100644 genplus-gx/gx/images/Main_logo.png create mode 100644 genplus-gx/gx/images/Main_options.png create mode 100644 genplus-gx/gx/images/Main_play_gcn.png create mode 100644 genplus-gx/gx/images/Main_play_wii.png create mode 100644 genplus-gx/gx/images/Main_quit.png create mode 100644 genplus-gx/gx/images/Main_reset.png create mode 100644 genplus-gx/gx/images/Main_showinfo.png create mode 100644 genplus-gx/gx/images/Main_takeshot.png create mode 100644 genplus-gx/gx/images/Option_ctrl.png create mode 100644 genplus-gx/gx/images/Option_menu.png create mode 100644 genplus-gx/gx/images/Option_sound.png create mode 100644 genplus-gx/gx/images/Option_system.png create mode 100644 genplus-gx/gx/images/Option_video.png create mode 100644 genplus-gx/gx/images/Overlay_bar.png create mode 100644 genplus-gx/gx/images/Snap_empty.png create mode 100644 genplus-gx/gx/images/Star_empty.png create mode 100644 genplus-gx/gx/images/Star_full.png create mode 100644 genplus-gx/gx/images/ctrl_classic.png create mode 100644 genplus-gx/gx/images/ctrl_gamecube.png create mode 100644 genplus-gx/gx/images/ctrl_nunchuk.png create mode 100644 genplus-gx/gx/images/ctrl_option_off.png create mode 100644 genplus-gx/gx/images/ctrl_option_on.png create mode 100644 genplus-gx/gx/images/ctrl_wiimote.png create mode 100644 genplus-gx/gx/images/generic_point.png create mode 100644 genplus-gx/gx/main.c create mode 100644 genplus-gx/gx/osd.h create mode 100644 genplus-gx/gx/sounds/button_over.pcm create mode 100644 genplus-gx/gx/sounds/button_select.pcm create mode 100644 genplus-gx/gx/sounds/intro.pcm create mode 100644 genplus-gx/gx/utils/oggplayer.c create mode 100644 genplus-gx/gx/utils/oggplayer.h create mode 100644 genplus-gx/gx/utils/vi_encoder.c create mode 100644 genplus-gx/gx/utils/vi_encoder.h create mode 100644 genplus-gx/libretro/jni/Android.mk create mode 100644 genplus-gx/libretro/jni/Application.mk create mode 100644 genplus-gx/libretro/libretro.c create mode 100644 genplus-gx/libretro/libretro.h create mode 100644 genplus-gx/libretro/link.T create mode 100644 genplus-gx/libretro/msvc/msvc-2003-xbox1.bat create mode 100644 genplus-gx/libretro/msvc/msvc-2003-xbox1.sln create mode 100644 genplus-gx/libretro/msvc/msvc-2003-xbox1/msvc-2003-xbox1.vcproj create mode 100644 genplus-gx/libretro/msvc/msvc-2003-xbox1/stdint.h create mode 100644 genplus-gx/libretro/msvc/msvc-2010-360.bat create mode 100644 genplus-gx/libretro/msvc/msvc-2010-360.sln create mode 100644 genplus-gx/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj create mode 100644 genplus-gx/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj.filters create mode 100644 genplus-gx/libretro/msvc/msvc-2010.sln create mode 100644 genplus-gx/libretro/msvc/msvc-2010/libretro.def create mode 100644 genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj create mode 100644 genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters create mode 100644 genplus-gx/libretro/osd.h create mode 100644 genplus-gx/libretro/qnx/playbook/.cproject create mode 100644 genplus-gx/libretro/qnx/playbook/.project create mode 100644 genplus-gx/libretro/scrc32.c create mode 100644 genplus-gx/libretro/scrc32.h create mode 100644 genplus-gx/sdl/CHANGELOG.txt create mode 100644 genplus-gx/sdl/LICENSE.txt create mode 100644 genplus-gx/sdl/Makefile.sdl create mode 100644 genplus-gx/sdl/README.txt create mode 100644 genplus-gx/sdl/config.c create mode 100644 genplus-gx/sdl/config.h create mode 100644 genplus-gx/sdl/error.c create mode 100644 genplus-gx/sdl/error.h create mode 100644 genplus-gx/sdl/fileio.c create mode 100644 genplus-gx/sdl/fileio.h create mode 100644 genplus-gx/sdl/icon.rc create mode 100644 genplus-gx/sdl/main.c create mode 100644 genplus-gx/sdl/main.h create mode 100644 genplus-gx/sdl/md.ico create mode 100644 genplus-gx/sdl/osd.h create mode 100644 genplus-gx/sdl/readme-sdl.txt create mode 100644 genplus-gx/sdl/unzip.c create mode 100644 genplus-gx/sdl/unzip.h create mode 100644 output/dll/libgenplusgx.dll diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 0069e9a6a1..ba260f7245 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -3219,8 +3219,11 @@ namespace BizHawk.Client.EmuHawk nextEmulator = new PCEngine(nextComm, game, rom.RomData); break; case "GEN": - nextEmulator = new Genesis(nextComm, game, rom.RomData); - break; + { + //nextEmulator = new Genesis(nextComm, game, rom.RomData); + nextEmulator = new BizHawk.Emulation.Cores.Consoles.Sega.gpgx.GPGX(nextComm, rom.RomData, "GEN"); + break; + } case "TI83": nextEmulator = new TI83(nextComm, game, rom.RomData); if (Global.Config.TI83autoloadKeyPad) diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index ba6064dafa..c3fe608365 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -408,6 +408,8 @@ + + diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs new file mode 100644 index 0000000000..89bbe4f05c --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs @@ -0,0 +1,280 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using BizHawk.Common; +using BizHawk.Emulation.Common; + +using System.Runtime.InteropServices; + + +namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx +{ + public class GPGX : IEmulator, ISyncSoundProvider, IVideoProvider + { + static GPGX AttachedCore = null; + + byte[] romfile; + + bool disposed = false; + + LibGPGX.load_archive_cb LoadCallback = null; + + public GPGX(CoreComm NextComm, byte[] romfile, string romextension) + { + try + { + CoreComm = NextComm; + if (AttachedCore != null) + { + AttachedCore.Dispose(); + AttachedCore = null; + } + AttachedCore = this; + + MemoryDomains = MemoryDomainList.GetDummyList(); + + LoadCallback = new LibGPGX.load_archive_cb(load_archive); + + this.romfile = romfile; + + if (!LibGPGX.gpgx_init(romextension, LoadCallback)) + throw new Exception("gpgx_init() failed"); + } + catch + { + Dispose(); + throw; + } + } + + /// + /// core callback for file loading + /// + /// string identifying file to be loaded + /// buffer to load file to + /// maximum length buffer can hold + /// actual size loaded, or 0 on failure + int load_archive(string filename, IntPtr buffer, int maxsize) + { + byte[] srcdata = null; + + if (buffer == IntPtr.Zero) + { + Console.WriteLine("Couldn't satisfy firmware request {0} because buffer == NULL", filename); + return 0; + } + + if (filename == "PRIMARY_ROM") + srcdata = romfile; + else + { + // use corecomm for firmware requests + } + + if (srcdata != null) + { + if (srcdata.Length > maxsize) + { + Console.WriteLine("Couldn't satisfy firmware request {0} because {1} > {2}", filename, srcdata.Length, maxsize); + return 0; + } + else + { + Marshal.Copy(srcdata, 0, buffer, srcdata.Length); + Console.WriteLine("Firmware request {0} satisfied at size {1}", filename, srcdata.Length); + return srcdata.Length; + } + } + else + { + Console.WriteLine("Couldn't satisfy firmware request {0} for unknown reasons", filename); + return 0; + } + + } + + #region controller + + public ControllerDefinition ControllerDefinition { get { return NullEmulator.NullController; } } + public IController Controller { get; set; } + + #endregion + + public void FrameAdvance(bool render, bool rendersound = true) + { + IsLagFrame = true; + Frame++; + LibGPGX.gpgx_advance(); + update_video(); + update_audio(); + } + + public int Frame { get; private set; } + public int LagCount { get; set; } + public bool IsLagFrame { get; private set; } + + public string SystemId { get { return "GEN"; } } + public bool DeterministicEmulation { get { return true; } } + public string BoardName { get { return null; } } + + public CoreComm CoreComm { get; private set; } + + #region saveram + + public byte[] ReadSaveRam() + { + throw new NotImplementedException(); + } + + public void StoreSaveRam(byte[] data) + { + throw new NotImplementedException(); + } + + public void ClearSaveRam() + { + throw new NotImplementedException(); + } + + public bool SaveRamModified + { + get + { + return false; + } + set + { + throw new NotImplementedException(); + } + } + + #endregion + + public void ResetCounters() + { + Frame = 0; + IsLagFrame = false; + LagCount = 0; + } + + #region savestates + + public void SaveStateText(System.IO.TextWriter writer) + { + } + + public void LoadStateText(System.IO.TextReader reader) + { + } + + public void SaveStateBinary(System.IO.BinaryWriter writer) + { + } + + public void LoadStateBinary(System.IO.BinaryReader reader) + { + } + + public byte[] SaveStateBinary() + { + return new byte[0]; + } + + public bool BinarySaveStatesPreferred { get { return true; } } + + #endregion + + public MemoryDomainList MemoryDomains { get; private set; } + + public List> GetCpuFlagsAndRegisters() + { + return new List>(); + } + + public void Dispose() + { + if (!disposed) + { + if (AttachedCore != this) + throw new Exception(); + AttachedCore = null; + } + } + + #region SoundProvider + + short[] samples = new short[4096]; + int nsamp = 0; + + public ISoundProvider SoundProvider { get { return null; } } + public ISyncSoundProvider SyncSoundProvider { get { return this; } } + public bool StartAsyncSound() { return false; } + public void EndAsyncSound() { } + + public void GetSamples(out short[] samples, out int nsamp) + { + nsamp = this.nsamp; + samples = this.samples; + this.nsamp = 0; + } + + public void DiscardSamples() + { + this.nsamp = 0; + } + + void update_audio() + { + IntPtr src = IntPtr.Zero; + LibGPGX.gpgx_get_audio(ref nsamp, ref src); + if (src != IntPtr.Zero) + { + Marshal.Copy(src, samples, 0, nsamp * 2); + } + } + + #endregion + + #region VideoProvider + + public IVideoProvider VideoProvider { get { return this; } } + + int[] vidbuff = new int[0]; + int vwidth; + int vheight; + public int[] GetVideoBuffer() { return vidbuff; } + public int VirtualWidth { get { return BufferWidth; } } // TODO + public int BufferWidth { get { return vwidth; } } + public int BufferHeight { get { return vheight; } } + public int BackgroundColor { get { return unchecked((int)0xff000000); } } + + unsafe void update_video() + { + int pitch = 0; + IntPtr src = IntPtr.Zero; + + LibGPGX.gpgx_get_video(ref vwidth, ref vheight, ref pitch, ref src); + + if (vidbuff.Length < vwidth * vheight) + vidbuff = new int[vwidth * vheight]; + + int rinc = (pitch / 4) - vwidth; + fixed (int* pdst_ = &vidbuff[0]) + { + int* pdst = pdst_; + int* psrc = (int*)src; + + for (int j = 0; j < vheight; j++) + { + for (int i = 0; i < vwidth; i++) + *pdst++ = *psrc++ | unchecked((int)0xff000000); + psrc += rinc; + } + } + } + + #endregion + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs new file mode 100644 index 0000000000..8d38a126b9 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; + +namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx +{ + public static class LibGPGX + { + [DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void gpgx_get_video(ref int w, ref int h, ref int pitch, ref IntPtr buffer); + + [DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void gpgx_get_audio(ref int n, ref IntPtr buffer); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate int load_archive_cb(string filename, IntPtr buffer, int maxsize); + + [DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void gpgx_advance(); + + [DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern bool gpgx_init(string feromextension, load_archive_cb feload_archive_cb); + + } +} diff --git a/genplus-gx/HISTORY.txt b/genplus-gx/HISTORY.txt new file mode 100644 index 0000000000..fe8c528787 --- /dev/null +++ b/genplus-gx/HISTORY.txt @@ -0,0 +1,1023 @@ +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.7.4 (21/06/2013) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/SCD] +--------------- +* fixed access to read-only registers on Main-CPU side ("Batman Returns" platform level freeze) +* fixed & improved emulation of PRG-RAM write protection register ("Lunar Eternal Blue" japanese version freeze) +* improved SUB & MAIN-CPU synchronization ("Dracula Unleashed" freeze when using US Model 2 BIOS) +* improved CPU polling detection +* improved CDD emulation & added CD drive access time for SEEK command ("Panic!/Switch" intro missing scene) +* added missing reinitialization of MAIN-CPU PRG-RAM bank on reset +* added .OGG audio tracks support through LIBTREMOR + +[Core/Sound] +--------------- +* fixed YM2612 configurable DAC depth emulation +* improved Low-Pass filter +* added optional "MONO" output mode + +[Core/VDP] +--------------- +* fixed FIFO access timings when using invalid write code value ("Clue" menu) +* fixed DMA Copy with undocumented code value ("Fatal Labyrinth" end sequence) +* minor code fixes & optimizations + +[Core/CPU] +--------------- +* optimized 68k stack read/write functions +* fixed broken 68k address error emulation +* fixed 68k interrupt behavior (prevents interrupts from being executed multiple time when 68k is halted) +* fixed Z80 registers initial state, added proper initialization when using PBC (verified on real hardware by Charles McDonald) + +[Core/MD] +--------------- +* fixed SRAM incompatibilities between BIG ENDIAN & LITTLE ENDIAN platforms (note: this breaks old .srm files with LITTLE ENDIAN platform ports) +* added support for a few recently dumped unlicensed games +* added auto-detection of byte-swapped ROM files + +[Gamecube/Wii] +--------------- +* fixed CD Leds positioning when using NTSC filter +* improved on-screen CD Leds (thanks to Iceknight) +* various code fixes & improvements + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.7.3 (26/11/2012) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Gamecube/Wii] +--------------- +* fixed broken input system initialization + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.7.2 (24/11/2012) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/SCD] +--------------- +* added default TOC for Shadow of the Beast II (prevent hangs when audio tracks are missing) +* fixed CD-DA fader muting +* fixed PCM channels panning on reset +* fixed backup RAM file management when using disc swap with Mode 1 cartridge +* incremented CD drive read latency: fixes Space Adventure Cobra (freeze when opening coffin at 2nd morgue scene) +* improved CDD emulation accuracy: fixes Snatcher (freeze at the end of Act 2) & various CD player bugs +* improved MAIN-SUB memory map mirroring in SCD mode (verified on real hardware by Charles McDonald) +* implemented cycle-accurate "stopwatch" register emulation + +[Core/Sound] +--------------- +* fixed broken PSG noise frequency +* fixed incorrect Game Gear PSG stereo emulation +* implemented cycle-accurate Game Gear PSG stereo + +[Core/VDP] +--------------- +* fixed broken VDP DMA from SVP ROM latency (graphic errors in Virtua Racing) + +[Core/MD] +--------------- +* added Super Mario World 64 (unlicensed) cartridge hardware emulation + +[Core/Input] +--------------- +* added automatic detection for CD games with Justifier/Menacer support +* improved Justifier/Menacer emulation + +[Gamecube/Wii] +--------------- +* fixed screen rendering when borders are disabled +* added configurable on-screen CD leds + +[Wii] +--------------- +* DVD light now indicates when virtual CD tray is open +* fixed automatic input settings detection +* improved lightgun crosshair positionning + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.7.1 (13/10/2012) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/SCD] +--------------- +* added support for CUE files +* added CD-DA tracks emulation (needs CUE+BIN or ISO+WAV images) +* added CD fader emulation +* added CDD "Fast FW" & "Fast RW" commands emulation +* improved CDD TOC emulation (random freezes in Sonic CD, Switch/Panic, Final Fight CD and probably many others) +* improved PCM chip synchronization with SUB-CPU (missing speeches in Willy Beamish) +* fixed PCM chip emulation (random hangs in Snatcher, missing sound effects in Switch/Panic, Final Fight CD, Wonderdog...) +* fixed Word-RAM memory mode on soft-reset (missing logo gfx effects) +* fixed SUB-CPU access to unused areas when using PC-relative instructions (Final Fight CD first boss random crash) +* fixed CPU idle loop detection on memory mode register access (Pugsy CD first boss slowdown) +* fixed Mode 1 emulation (cartridge boot mode) + +[Core/Sound] +--------------- +* replaced FIR resampler by Blip Buffer for FM resampling +* modified SN76489 core for use of Blip Buffer +* improved PSG & FM chips synchronization using Blip Buffer +* added Game Gear PSG stereo support +* fixed SG-1000 specific PSG noise +* fixed YM2612 LFO AM waveform (California Games surfing event) +* fixed YM2612 phase precision +* minor optimizations to YM2612 core + +[Core/Game Gear] +--------------- +* added support for CJ Elephant Fugitive (recently released by SMS Power) +* added Game Gear extended screen option + +[Core/Genesis] +--------------- +* added support for a few recently dumped (but unreleased) games + +[Core/General] +--------------- +* improved ROM & CD image file loading +* various code cleanup + +[Gamecube/Wii] +--------------- +* added automatic disc swap feature +* removed automatic frameskipping (no use) +* improved general audio/video sync +* various code cleanup & bugfixes + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.7.0 (01/07/2012) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/SCD] +--------------- +* added Mega CD / Sega CD hardware emulation (incl. Sub 68K, CDD, CDC, PCM, GFX rotation/scaling, etc) +* added .ISO & .BIN CD image file support +* added 512K backup cartridge RAM support +* added savestate support for CD games + +NOTES: +~~~~~~ +* to play CD games, original BIOS ROM files are required in /genplus/bios/ directory: unzip & rename them to bios_CD_U.bin, bios_CD_E.bin, bios_CD_J.bin +* CD audio tracks (CD-DA) are not supported (yet) + +[Core/CPU] +--------------- +* modified 68k core for Mega CD / Sega CD support +* optimized 68k core using prebuild const tables + +[Core/VDP] +--------------- +* improved DMA accuracy +* improved accuracy of nametables register & VSRAM writes during HBLANK: fixes "The Adventures of Batman & Robin" (graphical issues during 2nd Boss fight). +* added support for 8-bit VRAM writes with undocumented code value (verified on real hardware by Nemesis) + +[Core/Sound] +--------------- +* improved synchronization between SN76489 & YM2162 cores. +* improved accuracy of SN76489 core timings. + +[Core/MD] +--------------- +* added support for some recently dumped unlicensed games. +* improved emulation of 32k bankswitch hardware used by a few unlicensed games. +* fixed behavior of Z80 banked reads from 68k RAM (verified on real hardware). +* fixed support for 128K Pro Action Replay ROM. + +[Core/MS] +--------------- +* added support for all recent korean ROM dumps by SMS Power. +* added emulation of korean multi-game mapper (4-Pak All Action) +* added pseudo-random RAM pattern initialization on Mark-III and Japanese Master System (fixes "Alibaba and 40 Thieves" & "Block Hole") +* added port $3E emulation & internal BOOTROM support (Master System & Game Gear only). + +[Core/General] +--------------- +* added an option to set VDP mode (PAL/NTSC) independently from console region. +* added an option to select original system master clock frequency (PAL/NTSC/AUTO), emulation will run at selected frequency when VSYNC is disabled. +* fixed 68k context loading/saving (Sol Deace). +* fixed C89 incompatibilities for better portability. +* removed use of "long int" type for portability on 64-bit platforms. +* moved savestate zlib compression out of emulation core (for ports that don't use it). +* various optimizations. + +[Gamecube/Wii] +--------------- +* removed ROM load device selection from Load Menu: default ROM device must now be configured in menu settings. +* added specific load buttons, browsers & saved paths for each systems, this also fixes slowdowns caused by screenshot loading when browsing from slow devices. +* added support for left/right buttons as page up/down keys in ROM browsers +* added right analog stick as default "return to menu" key for Gamecube controllers +* added alternate remappable menu key combo for Gamecube controllers +* added an option to disable VSYNC (emulator is synced with audio hardware instead of video). +* added an option to boot system from "BIOS", with or without cartridge. +* added Master System & Game Gear "BIOS" support (files should be named bios_U.sms, bios_J.sms, bios_E.sms & bios.gg and copied to /genplus/bios directory). +* replaced "Hard Reset" button by a Soft Reset for systems having a Reset button (Mega Drive / Genesis & Master System) +* State & SRAM files are now only compressed when saving to Gamecube Memory Cards +* various fixes & cleanup. +* compiled with devkitPPC r26 & libogc 1.8.11. + +[Gamecube] +---------- +* improved progressive mode support when component cable is detected (hold B during startup to switch menu video mode configuration) + + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.6.0 (07/08/2011) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/Sound] +--------------- +* added YM2413 emulation in Master System compatibility mode. +* fixed SN76489 noise boost initialization. +* minor YM2612 core optimizations. + +[Core/VDP] +--------------- +* added accurate emulation of SG-1000, Master System (315-5124, 315-5246) & Game Gear VDP. +* added support for all TMS9918 rendering modes. +* improved Mega Drive VDP timings accuracy in Master System Compatibility mode. +* fixed color palette initialization. +* fixed shifted sprites rendering in Mode 4. +* modified pixel rendering support (pixel depth is now forced at compilation time). + +[Core/CPU] +--------------- +* optimized 68k core (rewrote 68k interrupt handling, removed multiple CPU types support & unused code) for 5~8% speed improvment + +[Core/IO] +--------------- +* added accurate emulation of Master System (315-5216, 315-5237, 315-5297) & Game Gear I/O controllers. +* added Terebi Oekaki tablet emulation. +* improved Mouse emulation (fixes mouse support in Cannon Fodder). +* improved Justifier emulation (fixes gun support in Lethal Enforcers 2). +* improved 6-Buttons control pad emulation (fixes Duke Nukem 3D) +* modified lightgun emulation to use common key inputs for all devices. +* 2-buttons controller is now picked by default for Master System games. + +[Core/MD] +--------------- +* added copy-protection hardware emulation for some new dumped games (Tiny Toon Adventures 3, Mighty Morphin Power Rangers & The Battle of Red Cliffs). +* added Game Toshokan in EEPROM database (verified on real cartridge). +* fixed Micro Machines 2 - Turbo Tournament EEPROM size (verified on real cartridge). +* modified SRAM banswitch hardware emulation to be more compatible with some hacks. + +[Core/MS] +--------------- +* added Cyborg Z to Korean mapper database. +* +[Core/GG] +--------------- +* added 93C46 EEPROM emulation (Majors Pro Baseball, World Series Baseball & World Series Baseball 95). + +[Core/General] +--------------- +* added support for .mdx ROM format. +* added Game Gear & SG-1000 ROM support. +* added accurate emulation of SG-1000, Master System (I, II) & Game Gear hardware models for 100% compatibility. +* updated to new Genesis Plus license (see http://cgfm2.emuviews.com/) +* various code cleanup. + +[Gamecube/Wii] +--------------- +* IMPORTANT: cheats, screenshots & save files are now stored in console-specific directories (ex: /snaps/md, /cheats/ms, /saves/gg, ...) +* added 8-bit Action Replay & Game Genie codes support (for Master System & Game Gear games). +* improved audio/video synchronization for PAL games in 50Hz TV modes (now use VSYNC like NTSC games in 60hz modes). +* improved gun cursor positioning accuracy. +* improved horizontal scaling & screenshots rendering in H32 mode. +* fixed a bug with ROM file extension handling that would affect cheats, snapshots, sram & savestate files. +* removed ARAM/injected ROM support (unused). +* removed WPAD_ and PAD_ update from VSYNC callback. +* increased GCC inlining limits for some speed improvment. +* compiled with devkitPPC r24 & libogc 1.8.7. + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.5.0 (31/03/2011) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/VDP] +--------------- +* added support for Master System compatibility mode (Z80 ports access mode), incl. Mode 5 rendering. +* added Mode 4 rendering for both Genesis & Master System modes. +* added alternate BG planes rendering functions (should be faster on PPC architectures). + +[Core/IO] +--------------- +* added support for Master System compatibility mode (Z80 ports access mode). +* added Master System peripherals emulation (Control Pad, Paddle, Sports Pad & Light Phaser). +* added XE-1AP (analog controller) emulation. +* added Activator emulation. + +[Core/Extra] +--------------- +* added support for all known Master System cartridge mappers. +* added copy-protection hardware emulation for a few MD unlicensed games: fixes 777 Casino (crash when talking to bunny girls). +(NB: most of those unlicensed games seem to have been already patched by ROM dumpers, main purpose is documenting them) +* added support for Top Shooter arcade board controller. (A=Shoot, B=Bet, C/RIGHT=Coins, START=Start, hold UP on startup to enter service mode) +* improved King of Fighters 98 mapper emulation (registers address decoding is now 100% accurate) +* fixed Game Genie when several codes affect same ROM address. +* fixed EEPROM types for Brian Lara Cricket & NBA Jam TE (verified on real cartridges) + +[Core/General] +--------------- +* added Master System compatibility mode emulation (automatically enabled when loading ROM file with .sms extension). +* improved savestate stability & compatibility (support for old 1.4.x savestates is preserved) +* various code cleanup & comments. + +[Gamecube/Wii] +--------------- +* fixed cheat codes handling when several codes affect same ROM address. +* improved input controller detection on menu exit. +* improved key remapping dialog box to match emulated device +* changed Menu key for Gamecube controller to allow MODE button mapping +* fixed DVD not being unmounted on swap (memory leak) + +[Wii only] +--------------- +* added USB mouse support for Sega Mouse emulation +* compiled with latest libogc: improves USB compatibility & fixes stability issues with Wiimotes. + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.4.1 (04/12/2010) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/VDP] +--------------- +* improved VBLANK flag accuracy, as observed on real hardware. +* improved DMA operations accuracy, writes are now performed on a scanline basis: fixes Gaiares (flickering title screen). +* improved DMA Fill timing accuracy. +* fixed DMA with bad code values: fixes Williams Arcade Classics (corrupted gfx after soft reset). +* fixed horizontal resolution changes during HBLANK: fixes Bugs Bunny in Double Trouble (2nd stage). +* fixed Vertical Counter in interlace mode 1, as observed on real hardware. +* fixed horizontal border width, as observed on real hardware. +* various code improvments & optimizations. + +[Core/Extra] +--------------- +* improved savestate format: added DMA, SVP, cartridge mapping & internal registers state informations +* improved unlicensed ROM mappers emulation +* added Chinese Fighters III mapper support +* added Top Fighter mapper support +* fixed Barver Battle Saga mapper support +* fixed cartridge hardware soft-reset (Game Genie, SVP, ...) +* fixed Game Genie registers byte reads + +[Gamecube/Wii] +--------------- +* added message box when inputs config uses disconnected controllers. +* added message box when settings are reseted to default on startup. +* fixed default inputs configuration. +* fixed memory leak in Cheat Menu causing spurious resets. +* added an option to enable/disable automatic cheat activation +* increased max number of cheat codes +* optimized cheat codes requiring RAM patching. +* improved default horizontal scaling to better match output from a real Mega Drive + +[Gamecube specific] +--------------- +* fixed inverted keys in cheat menu. +* fixed audio input frequency, now use exact audio hardware samplerate, as measured on my Game Cube (~48044 Hz), + (NB: Wii samplerate has been verified to be closer to 48000 Hz) + +[Wii specific] +--------------- +* added the possibility for any wiimotes to be used as input device, regardless of the connected expansion controller. +* fixed USB drive not being detected when application is loaded from USB (HBC), thanks to Tantric for the tips. + + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.4.0 (01/11/2010) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/Sound] +--------------- +* completely rewrote sound processing/mixing: sound chips are now clocked with exact output framerate +to ensure 100% smooth video & audio playback, with no lag or skipping, while rendering an accurate number +of samples per frame and keeping PSG & FM chips in sync. +* improved PSG & FM chips synchronization with CPU execution (fixed point precision). +* improved YM2612 core general accuracy (SSG-EG, CSM mode,...) (based upon Nemesis recent tests on real hardware) +* improved YM2612 LFO emulation accuracy: fixes "Spider-Man & Venom : Separation Anxiety" (intro) +* fixed YM2612 bug with Timer B: fixes "Langrisser Hikari II"/"Der Langrisser II" (Sega logo) +* fixed YM2612 context saving/loading. +* fixed YM2612 state on reset. +* removed outdated & less accurate Gens YM2612 core +* added configurable YM2612 DAC resolution emulation. +* added configurable & faster FIR resampler (thanks to Blargg & AamirM), removed libsamplerate support. +* added configurable Low-Pass filtering +* added configurable 3-Band Equalizer (thanks to Neil C). +* added an option to boost SN76489 Noise Channel. +* adjusted SN76489 cut-off frequency. +* implemented Blargg's blip buffer in SN76489 core (all channels are now lineary interpolated) + +[Core/VDP] +--------------- +* added support for CRAM writes during horizontal blanking (Striker, Zero the Kamikaze Squirrel,...) +* added support for 2-Cell vertical scrolling in Interlaced 2 mode +* added support for some undocumented mode register bits +* added proper emulation of HV Counter latch: fixes Sunset Riders intro +* added pixel-accurate emulation of mid-line display on/off (Nigel Mansell World Championship PAL, Ren & Stimpy's Invention PAL,...) +* improved 2-cell vscroll emulation accuracy, as verified on real hardware (Gynoug, Cutie Suzuki no Ringside Angel, Formula One, Kawasaki Superbike Challenge) +* improved FIFO timings accuracy: fixes Sol Deace intro +* improved sprite masking accuracy (thanks to Nemesis for his test program) +* improved sprites processing accuracy: fixes (un)masked sprites in Mickey Mania (3D level), Sonic 2 (VS mode). +* improved HBLANK flag timing accuracy: fixes Mega Turrican (Sky level) +* improved horizontal blanking & HINT/VINT occurence timing accuracy, as measured on real hardware. +* improved HCounter accuracy in 40-cell mode, as measured on real hardware. +* improved color accuracy in VDP highlight mode to match results observed on real hardware + +[Core/CPU] +--------------- +* updated Z80 core to last version (fixes interrupt Mode 0 timing and some BIT instructions). +* fixed some Z80 instructions timing. +* fixed state of Z80 registers on reset (sound issues with Defender & Defender 2 in Williams Arcade Classics) +* improved Z80 interrupt accuracy +* improved 68k accuracy (initial Reset timing + auto-vectored interrupts handling). +* improved 68k timing accuracy for DIVU/DVIS (thanks to Jorge Cwik) & MULU/MULS instructions. +* implemented 68k undocumented flags behavior for DIVU/DIVS instructions (Bloodshot / Battle Frenzy) +* improved Z80 & 68k cpu execution/synchronization accuracy by using Master Clock as common reference (now run exactly 3420 M-Cycles per line). +* modified Z80 & 68k cores to directly use external cycle count instead of intermediate counters. + +[Core/Extra] +--------------- +* added Game Genie hardware emulation. +* added Action Replay & Pro Action Replay hardware emulation (only preliminary Pro Action Replay 2 support). +* added Sonic & Knuckles "Lock-On" support. +* added Cartridge "Hot Swap" feature. +* added missing EEPROM support in more games. +* added VDP lock-out emulation (TMSS). +* improved emulation of copy-protection hardware found in some unlicensed cartridges (Mulan, Pocket Monsters II). +* fixed Realtec mapper emulation: fixes missing sound in Balloon Boy / Funny World. +* fixed lightgun auto-detection: fixes default cursor position in Lethal Enforcers II. +* enabled simultaneous use of multitap & J-CART (Super Skidmarks 6-player mode) +* lots of code cleanup, bugfixes & optimization. + + +[Gamecube/Wii] +--------------- +* implemented custom FONT engine (uses internal IPL font & GX hardware rendering). +* implemented custom GUI engine (uses GX hardware rendering & multithreading) +* implemented advanced menu interface (IR pointing, game snapshots, cheats & saves manager, visual & sound effects, BGM support, etc). +* improved audio/video synchronization to ensure 100% smooth video & audio playback. +* improved soft-reset button support, now works more like real Mega Drive / Genesis (model 1) reset button. +* improved lightgun cursors layout. +* added automatic ROM loading feature (last played game launches immediately when starting the emulator) +* added PAR codes and .pat files support +* fixed lot of stability issues and potential memory leaks. + +[Wii specific] +--------------- +* added Video Hardware "Gamma" control +* added Video Hardware "Trap Filter" control +* improved Mouse emulation through Wii remote +* compiled with devkitPPC r22 & libOGC 1.8.5 (includes SDHC & USB2 support through IOS58, removes DVDX support) + + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.3.1 (20/12/2008) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Gamecube/Wii] + +* improved sound engine +* modified frame synchronization (now use audio DMA interrupt) + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.3.0 (14/12/2008) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* YM2612 bugfixes (MAME core): + .fixed EG Decay->Substain transition when SL & DR are minimals: fix tracks #3 and #9 in "Mega Turrican" + .fixed a bug in SSG-EG emulation code: fix Level 1 music in "Alisia Dragoon" + .modified SSG-EG Decay End Level: fix some sound effects (ChainSaw, Zap...) in "Beavis & Butthead" + .improved Detune overflow accuracy: fix very high frequency sounds in many games + .fixed registers 0x20-0x26 Reset state: fix intro music in "B.O.B" + .reverted incorrect fix with KEY ON: fix "Flamethrower" sound effect in "Alien 3" and many others +* adjusted HCounter values: fixes line flickering in "Sonic 3D" bonus stage +* adjusted VINT timing: fixes hang-up in "V.R Troopers" +* improved HBLANK flag accuracy: fixes line flickering in "Gouketsuji Ichizoku" +* fixed broken Z80 access to WRAM: fixes hang-up in "Mamono Hunter Youko" +* modified JCART emulation: fixes corrupted tracks logo in "Micro Machines 2" +* added Blargg's NTSC Filters support (NTSC video artifacts emulation) +* optimized VDP rendering core, rewrote 68k interface (memory handlers, cycle execution, interrupts): greatly improved emulation speed + +[Gamecube/Wii] + +* remove slowest libsamplerate settings under "HQ YM2612" option, only keeps SRC_LINEAR (faster) and SRC_SINC_FAST (better) +* added an option to enable/disable bilinear filtering +* rewrote video engine: improved horizontal scaling (VI+GX), improved rendering speed (direct texture mapping) +* removed embedded font, (re)enabled IPL font support: now should works for Qoob users too (thanks to emukiddid) +* fixed "Reset" button behavior, now acts more like Genesis Reset button ;-) +* patched libfat for faster SDCARD accesses (thanks to svpe) +* SRAM and SaveState filenames are now based on the ROM filename (for FAT devices only) +* various bugfixes, menu tweaks and code cleanup + +[Gamecube] + +* added 480p support in menu + +[Wii] + +* implemented fast scrolling in menu using Wiimote D-PAD +* added "Power" button support +* added USB Storage support +* Widescreen menu fix +* *new* libogc 1.7.0 features: SDHC support, Wiimote shutdown button support + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 080826 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* YM2612(MAME): fixed LFO phase update for CH3 special mode: fix sound effects in Warlock & Aladdin (thanks to AamirM) +* YM2612(MAME): fixed EG attenuation level on "KEY ON": fix Ecco 2's splash sound +* YM2612(MAME): fixed SSG-EG emulation: fix Bubba'n Stix (Track 5) and many others +* YM2612(MAME): replaced sample interpolation with libsamplerate support, High Quality mode is now more accurate +* implemented cycle-accurate HINT timings: every timing sensitive games/demos are now *finally* working fine +* fixed a bug affecting CRAM/VSRAM DMA timings +* fixed Sprite Attribute Table address mask for VRAM writes +* improved accuracy of 68k access to Z80: fix music in Pacman 2 when entering PAUSE menu +* disabled "Address Error" emulation when UMK3 hack is loaded: fix game crashing after a round ends up +* added support for some more unlicensed games: Pocket Monster, King of Fighter 98, Soul Blade (credits to Haze) +* improved Menacer emulation: fix lightgun support in Body Count & T2: The Arcade Game +* added Konami Justifier emulation: fix lightgun support in Lethal Enforcers 1 & 2 +* added Sega Mouse emulation (Populous 2, Body Count, Shangai 2, Fun'n Games, ...) + +[Gamecube/Wii] + +* added Wiimote support for Menacer/Justifier/Mouse +* added DVD support in Wii mode (no modchip required) +* added "Gun cursor" option to enable/disable gun position display +* added "Invert Mouse" option to invert Sega Mouse vertical axe (required by some games) +* improved Controller options: Wiimote/Nunchuk and Classical Controllers can now be affected separately to ANY player + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 080716 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* adjusted (again) HINT timings: fix Double Dragon 2 (game freezed), hopefully does not break anything else +* fixed broken EEPROM support for Codemaster games +* modified input update timings: fix Dungeons & Dragons * Warriors of the Eternal Sun (thanks to Notaz) +* added support for "Ultimate Mortal Kombat Trilogy" hack (max. size supported is 10MBytes) +* added (VERY) preliminar support for PICO roms (credits to Notaz for his documentation) +* improved YM2612 emulation (credits to Nemesis for his tests on real hardware): + .implemented phase overflow emulation: improved fix for special music instrument used in Comix Zone, Flashback, Ariel, Shaq Fu... + .improved SSG-EG emulation in MAME core (also based on additional code from Alone Coder) + .improved Timers emulation accuracy + .improved Enveloppe Generator accuracy + .fixed Channel 3 CSM mode emulation + .implemented sample interpolation in MAME core to emulate the chip at original frequency (HQ YM2612 mode, from gens) + +[Gamecube/Wii] + +* added automatic alphabetical filesorting (Marty Disibio) +* added ROM History for faster ROM access (Marty Disibio) +* fixed a silly input bug in "ROM Infos" & "Game Genie" menus +* modified "Hard Reset" option +* improved display sharpness in original rendering mode (H40 cell mode only), filtering is now completely disabled +* enabled overscan emulation in "STRETCH" aspect mode also +* added support for horizontal wiimote handling in Menu (automatically used when the wiimote is not pointed towards the screen) +* improved Controller options + .prevented keys reconfiguration if device is not detected + .added support for up to 8 players (ISS Pro Deluxe, ...) + .each player can be affected to a custom device (GAMECUBE Pad, WIIMOTE/NUNCHUK or CLASSIC) + .added the ability to use classic controller & wiimote pad from the same port separately + .modified "soft-reset" key on the Wiimote to avoid "accidental" resets (now press Buttons + & * simultaneously) + .added MODE button mapping: use "START+Z" on gamepad or "Button Minus" on wiimote/classic (not reconfigurable) + .added automatic configuration save for controller options + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 080601 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* improved HCounter accuracy: fix graphic glitches in "Striker (Europe)" +* improved HINT timing accuracy: fix flickering in "Zero The Kamikaze Squirrel (USA)" +* improved rendering accuracy when backdrop color is modified during HBLANK (Road Rash I/II/III) +* fixed broken Game Genie support + +[Gamecube/Wii] + +* added full horizontal scaling (up to 720 pixels) when using "stretch" aspect mode (use Xscale to increase width) +* added progressive mode support (480p) in menu also +* added automatic SRAM/FreezeState support (OFF by default, check "system options") +* added automatic configuration file support +* /genplus/saves is now automatically created if it does not exist +* use libfat automatic SDCARD detection: default slot is now always used when accessing SDCARD +* assigned Reset Button to Genesis Soft-Reset + +[Wii] + +* added automatic TV mode detection (from SYSCONF), no more PAL60 version needed +* added option to return to Wii System Menu +* fixed "TP reload" option: now compatible with HB channel +* removed SD-Gekko support (Wii slot becomes default slot) +* added Wii SD slot support for SRAM & FreezeState files +* added Wiimote, Nunchuk & Classic controllers support through libwiiuse (see User Manual for default keys) +* added customizable key mapping (for each configurations: wiimote only, wiimote+nunchuk or classic) + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 080419 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* modified VINT timings a little bit: fix lockup during Desert Strike's intro +* corrected 68k interrupts handling: fix graphic glitches in Darius II/Sagaia + +[Gamecube/Wii] + +* fixed 60Hz "Bilinear" rendering mode (was broken in last release) +* fixed issue with the 1st file when browsing SDCARD through SD-Gekko +* fixed GX initialization: fix "freeze" issue that occured sometime when starting a game +* added "Wii Reboot" option +* added PAL 50hz support in menu (black borders) +* added progressive rendering mode support (480p) in Wii mode (not supported by the PAL60 version, use the other one !) +* compiled with a modified libogc: should definitely fix the PAL "red screen" issue for RGB-cable users (still use the PAL60 version !) + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 080406 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* updated SVP core: fix some perspective issues in Virtua Racing (thanks to Notaz) +* added internal SAT update during VRAM Fill: fix unmasked sprites during Battletech's intro +* fixed m68k core issues with gcc 4.2.3: fix Xperts, Lemmings 2, M1 Abrams Battle Tank +* forced YM2612 Enveloppe update: fix intro music in Batman&Robin (thanks to Aamir) + +[Gamecube/Wii] + +* removed not working DVD features (Wii mode only) +* fixed Timers with PAL roms +* added EURGB60 TV mode support: fix "red screen" issue with PAL Wii when using RGB cable +* added PAL50 TV mode support (PAL and NTSC roms), see video options +* added "TP reload" option, use "System Reboot" (Wii mode only) +* added Front SD rom loading support with LFN & subdirectory browsing (Wii mode only) + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 080301 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* added SVP emulation: Virtua Racing is now emulated (big thanks to Notaz and TascoDeluxe) +* fixed VDP registers behaviour when VDP Mode 4 is enabled: fix Bass Masters Classic Pro, Captain Planet & The Planeeters +* corrected a bug in DMA Fill operation: fix James Pond 3, Rockman World/Megaman Willy Wars (corrupted VRAM) +* corrected typo errors in CPU cycle counters update: fix optiom screen music in "College Slam" and probably others games. +* added preliminary support of undocumented YM2612 bug: fixes soundtracks of Shaq Fu, Spiderman, Comix Zone, Ariel and some others +* added support for mappers & copy protection devices used in many unlicensed/pirate cartridges (see cart_hw.c for details) +* rewrote memory handlers for better modularity and some (little) speedup +* reduced Savestate size + +[Gamecube] + +* compiled with last LibOGC (20080228): fix issues when unplugging controller, support for Wii mode (see release.txt) +* added "hard-coded" IPL font (no more direct access to BOOTROM): fix font problem for Qoob users +* added SDCARD Slot B support for loading Roms +* removed unused MAME PSG Core +* added 'Force DTACK' option for prototype games usually hanging on real hardware (example: Sonic Crackers) +* added an option to underclock SVP core (with default cycle count, Virtua Racing actually does not run fullspeed in GC mode) +* fixed frame timing in PAL mode +* fixed analog stick sensitivity + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 080107 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* fixed interleaved rom detection: roms with .smd extension should now work fine +* fixed a recently introduced bug in VDP registers writes: fixes bad colors in Toy Story (intro) +* updated list of games using EEPROM: added Sports Talk Baseball (internal memory check fixed) and Brian Lara Cricket +* fixed VINT flag update when VINT is disabled: fixes NCAA College Football +* adjusted DMA timings in H32 mode: fixes flickering in Out of this World, Kawasaki Superbike Challenge & Formula One +* adjusted line rendering and HBLANK timings: fixes flickering in Nigel Mansell's World Championship Racing, Deadly Moves/Power Athlete +* fixed unmapped ROM reads through Z80 Bank: fixes Zombie High (Proto) +* added support for custom ROM/RAM mapping used by Game no Kanzume Otokuyou + +[Gamecube] + +* fixed broken SDCARD support for SRAM and Savestate files + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 071230 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Gamecube] + +* fixed ROM injector base address (DATA section 1) + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 071228 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* many sourcecode cleanup and optimization +* completely rewrote EEPROM emulation: now support all known EEPROM types (24C01-24C65) and mappers (Sega, Acclaim, EA, Codemasters) +used in a few games (now use internal game database) as external RAM. This should at least fix save support in the following games: + . NBA Jam (alternate Acclaim mapper) + . College Slam, Frank Thomas Big Hurt Baseball (24C65 type) + . NHLPA Hockey 93, Rings of Power (EA mapper) + . Micro Machines serie, Brian Lara Cricket 96/Shane Warne Cricket (Codemasters mapper) +* external RAM is now initialized to 0xFF by default: fix Micromachines 2, Dino Dini Soccer +* fixed SRAM 16-bits memory handlers: fix some Sega Sports and EA Sports games (NFL95, NBA Action 95, NHL97, NHL98,...) +* modified WRITE_xxx & READ_xxx macros for better portability and faster memory access on BIG ENDIAN platform +* completely rewrote BIG ENDIAN support in render.c and vdp.c: rendering should be a little faster +* rewrote ROM bankswitch emulation (Super Street Fighter II): ROM access are faster, using memory pointers instead of reading ROM copy from ARAM +* fixed leftmost Window/PlaneA column render and implemented Window bug (as described by Charles Mc Donald) +* improved "Sprite Limit" and "Sprite Collision" detection accuracy +* modified RGB565 Color Palette to use the full available color range (0-31;0-63) +* implemented "cycle accurate" HV Interrupt timings: fix Sesame's Street Counting Cafe, Legend of Galahad (intro) +* improved VDP access timings accuracy (added FIFO emulation): fix Double Clutch +* improved DMA timings accuracy: fix Winter Olympics (E), Arch Rivals and probably more +* fixed HCounter again: Road Rash serie (I,II,III) don't need timing hacks anymore +* fixed VCounter in Interlaced 2 mode: fix Combat Cars "VS-Mode" +* improved Interlaced 2 mode (double resolution) rendering: Sonic 2, Combat Cars ("VS-Modes") look far better +* added TMSS BIOS support (optional) +* rewrote part of the YM2162 MAME's core: fixed internal FM timers handling, removed non-YM2612 emulation code and unused multiple cpu support +* implemented "cycle accurate" FM timers & sound samples rendering +* improved Z80 Interrupt timing accuracy: fix Sonic 3 music slowdowns +* updated Z80 & 68000 cores to last MAME versions +* improved Soft Reset emulation: X-Men 2 and Eternal Champions (random character selection) now work more like on real hardware. +* added full overscan emulation (vertical & horizontal borders) for "pixel perfect" aspect ratio (tested against a real genesis) + +[Gamecube] + +* fixed rom checksum calculation (only used for rom information) +* some modifications in GX rendering code. +* added support for original Genesis/Megadrive NTSC & PAL video modes: this makes games looking exactly as on original hardware (progressive rendering with reduced resolution) +* added "Aspect" option to switch between ORIGINAL (aspect ratio is fixed and borders are emulated) and MANUAL SET (horizontal and vertical scaling can be manually configured, borders are not emulated) +* added "Overscan" option to disable the original borders color and always use black borders (only used when ORIGINAL Aspect mode is enabled) +* added support for up to 720 pixels horizontal resolution (needed for proper aspect ratio emulation) +* added "TV Mode" option to enable automatic switching to PAL(50Hz) TV mode when the Genesis runs in PAL mode +* added "Xshift" & "Yshift" settings to let you adjust display area position while keeping the original aspect ratio +* added option to disable/enable SSG-EG support in FM cores: this special mode is indeed not properly emulated and some games might sound wrong when enabled +* removed "CPU Type" option, you can also now force Region (JAP/EUR/USA) without reseting the game, choose USA or JAP for 60hz, EUR for 50hz, this can be useful to bypass game region protection at startup. + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 070720 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* corrected TeamPlayer support: fix multiplayer in Gauntlet 4 (Sept. version), Pengo and a lot of others +* added J-Cart support: enable multiplayer in Codemasters games (Pete Sampras, Micromachines games, Super Skidmarks) +* added serial EEPROM autodetection: fix games with bad SRAM informations in header (NBA Jam TE) +* added SVP faking: display 2D graphics in Virtua Racing (the game is however still unplayable) +* added support for more internal IO registers: fixe some unlicensed games (Wisdom Tree games...) +* added preliminary support for unmapped protection device: fix some unlicensed games with special built-in hardware (Squirell King, Lion King 2...) +* added "Soft Reset" combo (in game, use L+Z triggers): this should be like pressing the RESET button on a real Genesis and this is required + in some games to enable special features or even complete the game (ex: X-Men). + +[Gamecube] + +* added separate configuration for PortA/PortB inputs (GAMEPAD, MULTITAP or NONE, see Joypad Config): this let you setting + PORTB as unplugged, which is needed in some games to access special modes or enable cheat codes (Alien Storm, X-Men...) +* Freezestate & SRAM files are now compressed (using zlib) +* FreezeState & SRAM files can now be saved/loaded to/from SDCARD: located in /genplus/saves/ from the root of your SDCARD +* changed initial ROMS directory for SDCARD user: now looking for /genplus/roms/ from the root of your SDCARD +* added user-transparent SRAM autoload (detection order is MCARD then SDCARD, SLOTA then SLOTB) +* "System reboot" is now used for console reboot and SD/PSO reload (if detected) +* added new font: now use original IPL font, extracted from Bootrom +* modified controls when going into the rom selection menu (DVD or SDCARD): + . use B button to go up one directory + . use Z button to quit the file selection menu + . use L/R triggers to go down/up one full page + . use Left/Right buttons or Analog stick to scroll the selected entry's filename when it can't be full displayed +* various menu rearrangment, minor bugfixes & sourcecode cleanup + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 070621 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* added Multitap support (EA 4-Way Play and Sega Teamplayer): allowed up to four players in games supporting those peripherals +* added partial Sega Menacer lightgun support: automatically set when detecting the 6-in-1 Menacer game + +[Gamecube] + +* added 4.7GB DVD support for WII drives (the maximal allowed size for Gamecube DVD is still 1.35GB) +* removed MPAL video timings, always use 60Hz NTSC: fix display problems for PAL wii users (no more PAL50 version needed) +* added Console Reboot option in main menu (IPL Reboot) + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 070518 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* you can now switch between FM cores without reseting the game. FM registers value are automatically restored when switching. +* removed the previous VINT timings modification because it brokes some games (Rocket Knight, Thunderforce III,...) +* added automatic Timing configuration (VDP latency, VINT timing & alternate Line Timing) at game loading, based upon specific romname detection. +This means you can still modify some of these options afterwards but they are now automatically set/unset when loading a game which need +special timing fixes. These fixes are also automatically desactivated when the current game doesn't need them. +For information, games that are actually detected and need special timings to run properly are: + .Legend of Galahad & Road Rash series (single line not rendered properly) + .Sesame Street Counting Cafe (don't boot) + .Chaos Engine/Soldiers of Fortune (graphic glitches on scrolling) + +[Gamecube] + +* modified PAL framesync a little bit: the 20ms period is now applied between the start of 2 consecutive frames, +no more between the end of the previous and the start of the next one, which seems more correct to me + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 070508 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* VINT timings are now a little more accurate: fixes Sesame's Street Counting Cafe +* SN76496 MAX_OUTPUT back to normal +* modified FB_WNOISE value in SN76496 core according to John Kortink's last informations +* added support for Maxim's PSG core, same as used in SMSPLUS (it becomes the default PSG core) +* updated FM core to the latest MAME version +* corrected DAC output level (fixes voices and some special FX being too low) +* added support for Gens YM2612 (FM) core (MAME's one still remains default FM core) + +[Gamecube] + +* corrected L & R buttons assignment: fixes Genesis X & Z buttons being inverted +* added configurable preamplification for each sound cores (see Emulator Options) +* added some other configurable sound options (boost overall volume, FM improvment for Gens YM2612) + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 070411 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* corrected MAX_OUTPUT value in SN76496 core: fix PSG sound (SFX) volume +* removed unused sound buffer allocation + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 070326 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Gamecube] + +* added DVD automount: automatically call libogc DVD_Mount function if ISO PVD reading failed (idea taken from softdev's last neocdredux release). This may be useful for loading roms from a DVD after booting from SDLOAD or after stopping DVD motor. +* added "DVD motor off" feature, like in others emulators +* corrected Memory Card mounting function: EXI_ProbeReset() function was never called if the first mounting attempt failed. Should fix some of the "Unable to mount memory card" errors. + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 070322 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Gamecube] + + * added SDCARD subdirectory browsing and LFN (255 char. max) support + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 070317 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + + * Color RAM update now always reset color 0 to border color (fix color glitches in Mortal Kombat,...) (thanks to Noop's for the idea) + +[Gamecube] + + * remove some rendering unused code (only used by DOS version of genesis plus) for little speedup + * added an option to enable alternate line rendering timing (fix single line error in Road Rash series and Legend of Galahad's Intro) + * added last Softdev's modifications (normalised memory access and ASM GU functions used intead of 'C' ones) for some speedup + * updated gcaram.c to be compatible with last libogc version + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 070309 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* little rendering code speedups +* modified HV counter tables (fix graphic glitches in Skitchin's sky, Lotus 2 Recs, Panorama Cotton, Dashin Desperados & maybe more) +* completely rewrote DMA timings emulation so that it works for all games (no more cpu freezing) +* added all DMA tranfer rates handling for each three DMA modes and added dma busy flag emulation +* modified interrupts handling on VDP register #0 and #1 writes (fix Lemmings status bar) +* added VDP RAM write latency (fix Chaos Engine/Soldier of Fortune gfx glitches) +* modified FM timers handling a bit (fix Vectorman2 music) +* corrected Sprite Limit rendering (fix Sonic 1 & Micromachines 2 title screens) +* corrected IO Registers writes (fix Decap' Attack controls, no more need for alternate input) +* corrected 6 Buttons Pad emulation (fix 6buttons detection in Mortal Kombat 3, Comix Zone and other 6-buttons compatible games) +* modified sound mixing a bit according to Generator sourcecode (FM and PSG ratios seems more correct) +* added separate CPU Region (USA, Europe, Japan,...) & Speed (PAL or NTSC) choice in menu options +* modified main frame synchro in PAL mode (fix sound glitch in this mode), thanks to Softdev for the solution +* added savestates support (go to SRAM menu, memory card supports only) + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX release 070207 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* fm timers fixed (fix missing music in Castle of Illusion, Quackshot, Undead Line, Wonderboy in Monster Lair, Cal 50, Turbo Outrun, Thundeforce 4 and maybe more) +* added complete EEPROM emulation (save support now works fine in Wonderboy5, Megaman Willy Wars, NBA Jam...) (credits to Notaz, adapted from Picodrive code) +* added preliminar dma timing emulation (fix bottom screen in Legend of Galahad) (credits to Notaz, adapted from Picodrive code) +* hack: clear Vint pending after Hint (INT level 4) acknowledge (fix Fatal Rewind) +* hack: modify read_bus16 to return a random value (fake fetch) (fix Time Killers) +* modified cpu execution timings, with more correct hblank and interrupts timing (fix ISS Deluxe, Double Dragon 2 and certainly more) (Based on Gens code) +* modified busreq mechanism: better synchro between z80 & 68k (no need to dejitter anymore) (Based on Gens code) +* added sprite collision detection (fix Strider 2) +* modified dma fill operation for big endian platform (fix Contra Hardcorps gfx garbage) + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX WIP 1.2 (Softdev) +--------------------------------------------------------------------------------------------------------- + +[Gamecube] + +* Added partial zip support (unzip.c) + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX WIP 1.1 (Softdev) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* sio.c added +* Added six button pad support from x86 Gens +* Additional changes based on Charles MacDonald's gen-hw.txt + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX WIP 1 - 7 March 2006 (Softdev) +--------------------------------------------------------------------------------------------------------- + +[Core] + +* Updated SN76496 driver + +[Gamecube] + +* Added GX Hardware Scaling + + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX WIP 0 (Softdev) +--------------------------------------------------------------------------------------------------------- + +[Gamecube] + +* initial port based on Genesis Plus 1.2a from Charles McDonald (http://cgfm2.emuviews.com/) diff --git a/genplus-gx/LICENSE.txt b/genplus-gx/LICENSE.txt new file mode 100644 index 0000000000..ea974bc4e7 --- /dev/null +++ b/genplus-gx/LICENSE.txt @@ -0,0 +1,621 @@ + +Unless otherwise explicitly stated, all code in Genesis Plus GX is released +under the following license: + +Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles MacDonald +Some portions copyright Nicola Salmoria and the MAME team +All rights reserved. + +Copyright (c) 2007-2013 Eke-Eke +All rights reserved. + +Redistribution and use of this code or any derivative works are permitted +provided that the following conditions are met: + +* Redistributions may not be sold, nor may they be used in a commercial +product or activity. + +* Redistributions that are modified from the original source must include the +complete source code, including the source code for all components used by a +binary built from the modified sources. However, as a special exception, the +source code distributed need not include anything that is normally distributed +(in either source or binary form) with the major components (compiler, kernel, +and so on) of the operating system on which the executable runs, unless that +component itself accompanies the executable. + +* Redistributions must reproduce the above copyright notice, this list of +conditions and the following disclaimer in the documentation and/or other +materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +---------------------------------------------------------------------------------------- + +TREMOR library is distributed under the following license: + +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +---------------------------------------------------------------------------------------- + + +NTSC Filter and Blip Buffer libraries are distributed under the +terms of the GNU Lesser General Public License (LGPL) + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + +---------------------------------------------------------------------------------------- + +Gamecube & Wii ports are linked with LIBASND library and includes code distributed under +the following license: + +Copyright (c) 2008 Hermes +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. +- The names of the contributors may not be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +---------------------------------------------------------------------------------------- + + + diff --git a/genplus-gx/Makefile.gc b/genplus-gx/Makefile.gc new file mode 100644 index 0000000000..8eb625ff0a --- /dev/null +++ b/genplus-gx/Makefile.gc @@ -0,0 +1,148 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC) +endif + +include $(DEVKITPPC)/gamecube_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := genplus_cube +BUILD := build_cube +SOURCES := core core/m68k core/z80 core/sound core/tremor core/ntsc core/input_hw core/cd_hw core/cart_hw core/cart_hw/svp \ + gx gx/utils gx/gui gx/fileio gx/images gx/sounds +INCLUDES := core core/m68k core/z80 core/sound core/tremor core/ntsc core/input_hw core/cd_hw core/cart_hw core/cart_hw/svp \ + gx gx/utils gx/gui gx/fileio gx/images gx/sounds \ + $(BUILD) + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -O3 -fomit-frame-pointer --param large-function-growth=800 --param inline-unit-growth=200 -Wall -Winline -Wno-strict-aliasing $(MACHDEP) $(INCLUDE) -DUSE_LIBTREMOR -DDISABLE_MANY_OGG_OPEN_FILES -DUSE_16BPP_RENDERING -DALT_RENDERER +CXXFLAGS = $(CFLAGS) + +LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lpng -lfat -liso9660 -lasnd -logc -lm -lz + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) +PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) +PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm))) +OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD := $(CC) +else + export LD := $(CXX) +endif + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(PNGFILES:.png=.png.o) $(PCMFILES:.pcm=.pcm.o) $(OGGFILES:.ogg=.ogg.o) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) -I$(PORTLIBS)/include + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.gc + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the various extension +#--------------------------------------------------------------------------------- +%.jpg.o : %.jpg + @echo $(notdir $<) + $(bin2o) + +%.png.o : %.png + @echo $(notdir $<) + $(bin2o) + +%.pcm.o : %.pcm + @echo $(notdir $<) + $(bin2o) + +%.ogg.o : %.ogg + @echo $(notdir $<) + $(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/genplus-gx/Makefile.libretro b/genplus-gx/Makefile.libretro new file mode 100644 index 0000000000..2b5174cd39 --- /dev/null +++ b/genplus-gx/Makefile.libretro @@ -0,0 +1,235 @@ +DEBUG = 0 +LOGSOUND = 0 +FRONTEND_SUPPORTS_RGB565 = 1 + +GENPLUS_SRC_DIR := core +LIBRETRO_DIR := libretro + +ifeq ($(platform),) +platform = unix +ifeq ($(shell uname -a),) + platform = win +else ifneq ($(findstring MINGW,$(shell uname -a)),) + platform = win +else ifneq ($(findstring Darwin,$(shell uname -a)),) + platform = osx +else ifneq ($(findstring win,$(shell uname -a)),) + platform = win +endif +endif + +# system platform +system_platform = unix +ifeq ($(shell uname -a),) +EXE_EXT = .exe + system_platform = win +else ifneq ($(findstring Darwin,$(shell uname -a)),) + system_platform = osx +else ifneq ($(findstring MINGW,$(shell uname -a)),) + system_platform = win +endif + +TARGET_NAME := genesis_plus_gx + +ifeq ($(platform), unix) + TARGET := $(TARGET_NAME)_libretro.so + fpic := -fPIC + SHARED := -shared -Wl,--version-script=libretro/link.T -Wl,--no-undefined -lz + ENDIANNESS_DEFINES := -DLSB_FIRST + PLATFORM_DEFINES := -DHAVE_ZLIB +else ifeq ($(platform), osx) + TARGET := $(TARGET_NAME)_libretro.dylib + fpic := -fPIC + SHARED := -dynamiclib -lz + ENDIANNESS_DEFINES := -DLSB_FIRST + PLATFORM_DEFINES := -DHAVE_ZLIB +else ifeq ($(platform), ios) + TARGET := $(TARGET_NAME)_libretro_ios.dylib + fpic := -fPIC + SHARED := -dynamiclib -lz + ENDIANNESS_DEFINES := -DLSB_FIRST + PLATFORM_DEFINES := -DHAVE_ZLIB + + CC = clang -arch armv7 -isysroot $(IOSSDK) +else ifeq ($(platform), qnx) + TARGET := $(TARGET_NAME)_libretro_qnx.so + fpic := -fPIC + SHARED := -lm -shared -Wl,--version-script=libretro/link.T -Wl,--no-undefined -lz + ENDIANNESS_DEFINES := -DLSB_FIRST + PLATFORM_DEFINES := -DHAVE_ZLIB + CC = qcc -Vgcc_ntoarmv7le + AR = qcc -Vgcc_ntoarmv7le + PLATFORM_DEFINES := -D__BLACKBERRY_QNX__ -marm -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp +else ifeq ($(platform), ps3) + TARGET := $(TARGET_NAME)_libretro_ps3.a + CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe + AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe + PLATFORM_DEFINES := -D__CELLOS_LV2 -DALT_RENDER + STATIC_LINKING = 1 +else ifeq ($(platform), sncps3) + TARGET := $(TARGET_NAME)_libretro_ps3.a + CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe + AR = $(CELL_SDK)/host-win32/sn/bin/ps3snarl.exe + PLATFORM_DEFINES := -D__CELLOS_LV2 -DALT_RENDER + STATIC_LINKING = 1 +else ifeq ($(platform), psl1ght) + TARGET := $(TARGET_NAME)_libretro_psl1ght.a$(EXE_EXT) + CC = $(PS3DEV)/ppu/bin/ppu-gcc$(EXE_EXT) + AR = $(PS3DEV)/ppu/bin/ppu-ar$(EXE_EXT) + PLATFORM_DEFINES := -D__CELLOS_LV2 -DALT_RENDER + STATIC_LINKING = 1 +else ifeq ($(platform), psp1) + TARGET := $(TARGET_NAME)_libretro_psp1.a$(EXE_EXT) + CC = psp-gcc$(EXE_EXT) + AR = psp-ar$(EXE_EXT) + ENDIANNESS_DEFINES := -DLSB_FIRST + PLATFORM_DEFINES := -DPSP + CFLAGS += -G0 + STATIC_LINKING = 1 +else ifeq ($(platform), xenon) + TARGET := $(TARGET_NAME)_libretro_xenon360.a + CC = xenon-gcc$(EXE_EXT) + AR = xenon-ar$(EXE_EXT) + PLATFORM_DEFINES := -D__LIBXENON__ -DALT_RENDER + STATIC_LINKING = 1 +else ifeq ($(platform), ngc) + TARGET := $(TARGET_NAME)_libretro_ngc.a + CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) + AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) + PLATFORM_DEFINES := -DGEKKO -DHW_DOL -mrvl -mcpu=750 -meabi -mhard-float -DALT_RENDER + STATIC_LINKING = 1 +else ifeq ($(platform), wii) + TARGET := $(TARGET_NAME)_libretro_wii.a + CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) + AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) + PLATFORM_DEFINES := -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float -DALT_RENDER + STATIC_LINKING = 1 +else + TARGET := $(TARGET_NAME)_libretro.dll + CC = gcc + SHARED := -shared -static-libgcc -static-libstdc++ -Wl,--version-script=libretro/link.T -Wl,--no-undefined -lz + + ENDIANNESS_DEFINES := -DLSB_FIRST + PLATFORM_DEFINES := -DHAVE_ZLIB +endif + +ifeq ($(DEBUG), 1) + CFLAGS += -O0 -g +else +ifeq ($(platform),qnx) + CFLAGS += -Os -DNDEBUG +else + CFLAGS += -O3 -DNDEBUG +endif +endif + +LIBRETRO_SRC := $(GENPLUS_SRC_DIR)/genesis.c \ + $(GENPLUS_SRC_DIR)/vdp_ctrl.c \ + $(GENPLUS_SRC_DIR)/vdp_render.c \ + $(GENPLUS_SRC_DIR)/system.c \ + $(GENPLUS_SRC_DIR)/io_ctrl.c \ + $(GENPLUS_SRC_DIR)/loadrom.c \ + $(GENPLUS_SRC_DIR)/mem68k.c \ + $(GENPLUS_SRC_DIR)/state.c \ + $(GENPLUS_SRC_DIR)/memz80.c \ + $(GENPLUS_SRC_DIR)/membnk.c \ + $(GENPLUS_SRC_DIR)/input_hw/activator.c \ + $(GENPLUS_SRC_DIR)/input_hw/gamepad.c \ + $(GENPLUS_SRC_DIR)/input_hw/input.c \ + $(GENPLUS_SRC_DIR)/input_hw/lightgun.c \ + $(GENPLUS_SRC_DIR)/input_hw/mouse.c \ + $(GENPLUS_SRC_DIR)/input_hw/paddle.c \ + $(GENPLUS_SRC_DIR)/input_hw/sportspad.c \ + $(GENPLUS_SRC_DIR)/input_hw/teamplayer.c \ + $(GENPLUS_SRC_DIR)/input_hw/xe_a1p.c \ + $(GENPLUS_SRC_DIR)/input_hw/terebi_oekaki.c \ + $(GENPLUS_SRC_DIR)/cd_hw/cd_cart.c \ + $(GENPLUS_SRC_DIR)/cd_hw/cdc.c \ + $(GENPLUS_SRC_DIR)/cd_hw/cdd.c \ + $(GENPLUS_SRC_DIR)/cd_hw/gfx.c \ + $(GENPLUS_SRC_DIR)/cd_hw/pcm.c \ + $(GENPLUS_SRC_DIR)/cd_hw/scd.c \ + $(GENPLUS_SRC_DIR)/cart_hw/areplay.c \ + $(GENPLUS_SRC_DIR)/cart_hw/md_cart.c \ + $(GENPLUS_SRC_DIR)/cart_hw/sms_cart.c \ + $(GENPLUS_SRC_DIR)/cart_hw/eeprom_93c.c \ + $(GENPLUS_SRC_DIR)/cart_hw/eeprom_i2c.c \ + $(GENPLUS_SRC_DIR)/cart_hw/eeprom_spi.c \ + $(GENPLUS_SRC_DIR)/cart_hw/ggenie.c \ + $(GENPLUS_SRC_DIR)/cart_hw/sram.c \ + $(GENPLUS_SRC_DIR)/cart_hw/svp/ssp16.c \ + $(GENPLUS_SRC_DIR)/cart_hw/svp/svp.c \ + $(GENPLUS_SRC_DIR)/ntsc/md_ntsc.c \ + $(GENPLUS_SRC_DIR)/ntsc/sms_ntsc.c \ + $(GENPLUS_SRC_DIR)/sound/eq.c \ + $(GENPLUS_SRC_DIR)/sound/sound.c \ + $(GENPLUS_SRC_DIR)/sound/ym2612.c \ + $(GENPLUS_SRC_DIR)/sound/ym2413.c \ + $(GENPLUS_SRC_DIR)/sound/sn76489.c \ + $(GENPLUS_SRC_DIR)/sound/blip_buf.c \ + $(GENPLUS_SRC_DIR)/z80/z80.c \ + $(GENPLUS_SRC_DIR)/m68k/m68kcpu.c \ + $(GENPLUS_SRC_DIR)/m68k/s68kcpu.c \ + $(LIBRETRO_DIR)/libretro.c + +LIBRETRO_OBJ := $(LIBRETRO_SRC:.c=.o) + +ifeq ($(LOGSOUND), 1) +LIBRETRO_CFLAGS := -DLOGSOUND +endif + +DEFINES := +CFLAGS += $(fpic) $(DEFINES) $(CODE_DEFINES) + +ifeq ($(FRONTEND_SUPPORTS_RGB565), 1) +# if you have a new frontend that supports RGB565 +BPP_DEFINES = -DUSE_16BPP_RENDERING -DFRONTEND_SUPPORTS_RGB565 +else +BPP_DEFINES = -DUSE_15BPP_RENDERING +endif + +LIBRETRO_CFLAGS += -I$(GENPLUS_SRC_DIR) \ + -I$(GENPLUS_SRC_DIR)/sound \ + -I$(GENPLUS_SRC_DIR)/input_hw \ + -I$(GENPLUS_SRC_DIR)/cart_hw \ + -I$(GENPLUS_SRC_DIR)/cd_hw \ + -I$(GENPLUS_SRC_DIR)/cart_hw/svp \ + -I$(GENPLUS_SRC_DIR)/m68k \ + -I$(GENPLUS_SRC_DIR)/z80 \ + -I$(GENPLUS_SRC_DIR)/ntsc \ + -I$(LIBRETRO_DIR) \ + $(BPP_DEFINES) \ + $(ENDIANNESS_DEFINES) \ + $(PLATFORM_DEFINES) \ + -D__LIBRETRO__ + +ifeq ($(platform), qnx) + LIBRETRO_CFLAGS += -D__inline__=inline +else + LIBRETRO_CFLAGS += -DINLINE="static inline" +endif + +LIBRETRO_LIBS := -lm + + +all: $(TARGET) + +%.o: %.c + $(CC) -o $@ -c $< $(CFLAGS) $(LIBRETRO_CFLAGS) + +$(TARGET): $(LIBRETRO_OBJ) +ifeq ($(STATIC_LINKING), 1) + $(AR) rcs $@ $(LIBRETRO_OBJ) +else + $(CC) -o $(TARGET) $(fpic) $(LIBRETRO_OBJ) $(LIBRETRO_LIBS) $(SHARED) +endif + +clean-objs: + rm -f $(LIBRETRO_OBJ) + +clean: + rm -f $(LIBRETRO_OBJ) + rm -f $(TARGET) + +.PHONY: clean clean-objs + diff --git a/genplus-gx/Makefile.wii b/genplus-gx/Makefile.wii new file mode 100644 index 0000000000..10db880708 --- /dev/null +++ b/genplus-gx/Makefile.wii @@ -0,0 +1,148 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC) +endif + +include $(DEVKITPPC)/wii_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := genplus_wii +BUILD := build_wii +SOURCES := core core/m68k core/z80 core/sound core/tremor core/ntsc core/input_hw core/cd_hw core/cart_hw core/cart_hw/svp \ + gx gx/utils gx/gui gx/fileio gx/images gx/sounds +INCLUDES := core core/m68k core/z80 core/sound core/tremor core/ntsc core/input_hw core/cd_hw core/cart_hw core/cart_hw/svp \ + gx gx/utils gx/gui gx/fileio gx/images gx/sounds \ + $(BUILD) + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -O3 -fomit-frame-pointer --param large-function-growth=800 --param inline-unit-growth=200 -Wall -Winline -Wno-strict-aliasing $(MACHDEP) $(INCLUDE) -DUSE_LIBTREMOR -DUSE_16BPP_RENDERING -DALT_RENDERER -DHW_RVL +CXXFLAGS = $(CFLAGS) + +LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lpng -ldi -lfat -liso9660 -lasnd -lwiiuse -lbte -logc -lm -lz + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) +PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) +PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm))) +OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD := $(CC) +else + export LD := $(CXX) +endif + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(PNGFILES:.png=.png.o) $(PCMFILES:.pcm=.pcm.o) $(OGGFILES:.ogg=.ogg.o) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) -I$(PORTLIBS)/include + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.wii + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the various extension +#--------------------------------------------------------------------------------- +%.jpg.o : %.jpg + @echo $(notdir $<) + $(bin2o) + +%.png.o : %.png + @echo $(notdir $<) + $(bin2o) + +%.pcm.o : %.pcm + @echo $(notdir $<) + $(bin2o) + +%.ogg.o : %.ogg + @echo $(notdir $<) + $(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/genplus-gx/cinterface/cinterface.c b/genplus-gx/cinterface/cinterface.c new file mode 100644 index 0000000000..13cbb11471 --- /dev/null +++ b/genplus-gx/cinterface/cinterface.c @@ -0,0 +1,175 @@ +#include +#include +#include + +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + +#include "shared.h" +#include "libretro.h" +#include "state.h" +#include "genesis.h" +#include "md_ntsc.h" +#include "sms_ntsc.h" + +char GG_ROM[256] = "GG_ROM"; +char AR_ROM[256] = "AR_ROM"; +char SK_ROM[256] = "SK_ROM"; +char SK_UPMEM[256] = "SK_UPMEM"; +char GG_BIOS[256] = "GG_BIOS"; +char CD_BIOS_EU[256] = "CD_BIOS_EU"; +char CD_BIOS_US[256] = "CD_BIOS_US"; +char CD_BIOS_JP[256] = "CD_BIOS_JP"; +char MS_BIOS_US[256] = "MS_BIOS_US"; +char MS_BIOS_EU[256] = "MS_BIOS_EU"; +char MS_BIOS_JP[256] = "MS_BIOS_JP"; + +char romextension[4]; + +static uint32_t bitmap_data_[1024 * 512]; + +static int16 soundbuffer[4096]; +static int nsamples; + +#define GPGX_EX __declspec(dllexport) + +static int vwidth; +static int vheight; + +static void update_viewport(void) +{ + vwidth = bitmap.viewport.w + (bitmap.viewport.x * 2); + vheight = bitmap.viewport.h + (bitmap.viewport.y * 2); + + if (config.ntsc) + { + if (reg[12] & 1) + vwidth = MD_NTSC_OUT_WIDTH(vwidth); + else + vwidth = SMS_NTSC_OUT_WIDTH(vwidth); + } + + if (config.render && interlaced) + { + vheight = vheight * 2; + } +} + +GPGX_EX void gpgx_get_video(int *w, int *h, int *pitch, void **buffer) +{ + if (w) + *w = vwidth; + if (h) + *h = vheight; + if (pitch) + *pitch = bitmap.pitch; + if (buffer) + *buffer = bitmap.data; +} + +GPGX_EX void gpgx_get_audio(int *n, void **buffer) +{ + if (n) + *n = nsamples; + if (buffer) + *buffer = soundbuffer; +} + + +void osd_input_update(void) +{ +} + +int (*load_archive_cb)(const char *filename, unsigned char *buffer, int maxsize); + +// return 0 on failure, else actual loaded size +// extension, if not null, should be populated with the extension of the file loaded +// (up to 3 chars and null terminator, no more) +int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension) +{ + if (extension) + memcpy(extension, romextension, 4); + + return load_archive_cb(filename, buffer, maxsize); +} + +GPGX_EX void gpgx_advance(void) +{ + if (system_hw == SYSTEM_MCD) + system_frame_scd(0); + else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + system_frame_gen(0); + else + system_frame_sms(0); + + if (bitmap.viewport.changed & 1) + { + bitmap.viewport.changed &= ~1; + update_viewport(); + } + + nsamples = audio_update(soundbuffer); +} + + +GPGX_EX int gpgx_init(const char *feromextension, int (*feload_archive_cb)(const char *filename, unsigned char *buffer, int maxsize)) +{ + memset(&bitmap, 0, sizeof(bitmap)); + memset(bitmap_data_, 0, sizeof(bitmap_data_)); + + strncpy(romextension, feromextension, 3); + romextension[3] = 0; + + load_archive_cb = feload_archive_cb; + + bitmap.width = 1024; + bitmap.height = 512; + bitmap.pitch = 1024 * 4; + bitmap.data = (uint8_t *)bitmap_data_; + + /* sound options */ + config.psg_preamp = 150; + config.fm_preamp= 100; + config.hq_fm = 1; /* high-quality resampling */ + config.psgBoostNoise = 1; + config.filter= 0; /* no filter */ + config.lp_range = 0x9999; /* 0.6 in 16.16 fixed point */ + config.low_freq = 880; + config.high_freq= 5000; + config.lg = 1.0; + config.mg = 1.0; + config.hg = 1.0; + config.dac_bits = 14; /* MAX DEPTH */ + config.ym2413= 2; /* AUTO */ + config.mono = 0; /* STEREO output */ + + /* system options */ + config.system= 0; /* AUTO */ + config.region_detect = 0; /* AUTO */ + config.vdp_mode = 0; /* AUTO */ + config.master_clock= 0; /* AUTO */ + config.force_dtack = 0; + config.addr_error = 1; + config.bios = 0; + config.lock_on = 0; + + /* video options */ + config.overscan = 0; + config.gg_extra = 0; + config.ntsc = 0; + config.render= 0; + + if (!load_rom("PRIMARY_ROM")) + return 0; + + audio_init(44100, 0); + system_init(); + system_reset(); + + update_viewport(); + + return 1; +} + + diff --git a/genplus-gx/core/cart_hw/areplay.c b/genplus-gx/core/cart_hw/areplay.c new file mode 100644 index 0000000000..c27f8d86e0 --- /dev/null +++ b/genplus-gx/core/cart_hw/areplay.c @@ -0,0 +1,319 @@ +/**************************************************************************** + * Genesis Plus + * Action Replay / Pro Action Replay emulation + * + * Copyright (C) 2009-2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +#define TYPE_PRO1 0x12 +#define TYPE_PRO2 0x22 + +static struct +{ + uint8 enabled; + uint8 status; + uint8 *rom; + uint8 *ram; + uint16 regs[13]; + uint16 old[4]; + uint16 data[4]; + uint32 addr[4]; +} action_replay; + +static void ar_write_regs(uint32 address, uint32 data); +static void ar_write_regs_2(uint32 address, uint32 data); +static void ar_write_ram_8(uint32 address, uint32 data); + +void areplay_init(void) +{ + int size; + FILE *f; + + memset(&action_replay,0,sizeof(action_replay)); + + /* store Action replay ROM (max. 128k) & RAM (64k) above cartridge ROM + SRAM area */ + if (cart.romsize > 0x810000) return; + action_replay.rom = cart.rom + 0x810000; + action_replay.ram = cart.rom + 0x830000; + + /* Open Action Replay ROM */ + f = fopen(AR_ROM,"rb"); + if (f == NULL) return; + + /* ROM size */ + fseek(f, 0, SEEK_END); + size = ftell(f); + fseek(f, 0, SEEK_SET); + + /* detect Action Replay board type */ + switch (size) + { + case 0x8000: + { + /* normal Action Replay (32K) */ + action_replay.enabled = TYPE_AR; + + /* internal registers mapped at $010000-$01ffff */ + m68k.memory_map[0x01].write16 = ar_write_regs; + break; + } + + case 0x10000: + case 0x20000: + { + /* read Stack Pointer */ + uint8 sp[4]; + fread(&sp, 4, 1, f); + fseek(f, 0, SEEK_SET); + + /* Detect board version */ + if (sp[1] == 0x42) + { + /* PRO Action Replay 1 (64/128K) */ + action_replay.enabled = TYPE_PRO1; + + /* internal registers mapped at $010000-$01ffff */ + m68k.memory_map[0x01].write16 = ar_write_regs; + } + else if (sp[1] == 0x60) + { + /* PRO Action Replay 2 (64K) */ + action_replay.enabled = TYPE_PRO2; + + /* internal registers mapped at $100000-$10ffff */ + m68k.memory_map[0x10].write16 = ar_write_regs_2; + } + + /* internal RAM (64k), mapped at $420000-$42ffff or $600000-$60ffff */ + if (action_replay.enabled) + { + m68k.memory_map[sp[1]].base = action_replay.ram; + m68k.memory_map[sp[1]].read8 = NULL; + m68k.memory_map[sp[1]].read16 = NULL; + m68k.memory_map[sp[1]].write8 = ar_write_ram_8; + m68k.memory_map[sp[1]].write16 = NULL; + } + break; + } + + default: + { + break; + } + } + + if (action_replay.enabled) + { + /* Load ROM */ + int i = 0; + for (i=0; i> 1; + if (offset > 12) + { + m68k_unused_16_w(address,data); + return; + } + + /* update internal register */ + action_replay.regs[offset] = data; + + /* MODE register */ + if (action_replay.regs[3] == 0xffff) + { + /* check switch status */ + if (action_replay.status == AR_SWITCH_ON) + { + /* reset existing patches */ + areplay_set_status(AR_SWITCH_OFF); + areplay_set_status(AR_SWITCH_ON); + } + + /* enable Cartridge ROM */ + m68k.memory_map[0].base = cart.rom; + } +} + +static void ar_write_regs_2(uint32 address, uint32 data) +{ + /* enable Cartridge ROM */ + if (((address & 0xff) == 0x78) && (data == 0xffff)) + { + m68k.memory_map[0].base = cart.rom; + } +} + +static void ar_write_ram_8(uint32 address, uint32 data) +{ + /* byte writes are handled as word writes, with LSB duplicated in MSB (/LWR is not used) */ + *(uint16 *)(action_replay.ram + (address & 0xfffe)) = (data | (data << 8)); +} + diff --git a/genplus-gx/core/cart_hw/areplay.h b/genplus-gx/core/cart_hw/areplay.h new file mode 100644 index 0000000000..5f1befdab1 --- /dev/null +++ b/genplus-gx/core/cart_hw/areplay.h @@ -0,0 +1,52 @@ +/**************************************************************************** + * Genesis Plus + * DATEL Action Replay / Pro Action Replay emulation + * + * Copyright (C) 2009-2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _AREPLAY_H_ +#define _AREPLAY_H_ + +#define AR_SWITCH_OFF (0) +#define AR_SWITCH_ON (1) +#define AR_SWITCH_TRAINER (2) + +extern void areplay_init(void); +extern void areplay_shutdown(void); +extern void areplay_reset(int hard); +extern void areplay_set_status(int status); +extern int areplay_get_status(void); + +#endif diff --git a/genplus-gx/core/cart_hw/eeprom_93c.c b/genplus-gx/core/cart_hw/eeprom_93c.c new file mode 100644 index 0000000000..3e0a64f81d --- /dev/null +++ b/genplus-gx/core/cart_hw/eeprom_93c.c @@ -0,0 +1,249 @@ +/**************************************************************************** + * Genesis Plus + * Microwire Serial EEPROM (93C46 only) support + * + * Copyright (C) 2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "eeprom_93c.h" + +/* fixed board implementation */ +#define BIT_DATA (0) +#define BIT_CLK (1) +#define BIT_CS (2) + + +T_EEPROM_93C eeprom_93c; + +void eeprom_93c_init() +{ + /* default eeprom state */ + memset(&eeprom_93c, 0, sizeof(T_EEPROM_93C)); + eeprom_93c.data = 1; + eeprom_93c.state = WAIT_START; + sram.custom = 3; +} + +void eeprom_93c_write(unsigned char data) +{ + /* Make sure CS is HIGH */ + if (data & (1 << BIT_CS)) + { + /* Data latched on CLK postive edge */ + if ((data & (1 << BIT_CLK)) && !eeprom_93c.clk) + { + /* Current EEPROM state */ + switch (eeprom_93c.state) + { + case WAIT_START: + { + /* Wait for START bit */ + if (data & (1 << BIT_DATA)) + { + eeprom_93c.opcode = 0; + eeprom_93c.cycles = 0; + eeprom_93c.state = GET_OPCODE; + } + break; + } + + case GET_OPCODE: + { + /* 8-bit buffer (opcode + address) */ + eeprom_93c.opcode |= ((data >> BIT_DATA) & 1) << (7 - eeprom_93c.cycles); + eeprom_93c.cycles++; + + if (eeprom_93c.cycles == 8) + { + /* Decode instruction */ + switch ((eeprom_93c.opcode >> 6) & 3) + { + case 1: + { + /* WRITE */ + eeprom_93c.buffer = 0; + eeprom_93c.cycles = 0; + eeprom_93c.state = WRITE_WORD; + break; + } + + case 2: + { + /* READ */ + eeprom_93c.buffer = *(uint16 *)(sram.sram + ((eeprom_93c.opcode & 0x3F) << 1)); + eeprom_93c.cycles = 0; + eeprom_93c.state = READ_WORD; + + /* Force DATA OUT */ + eeprom_93c.data = 0; + break; + } + + case 3: + { + /* ERASE */ + if (eeprom_93c.we) + { + *(uint16 *)(sram.sram + ((eeprom_93c.opcode & 0x3F) << 1)) = 0xFFFF; + } + + /* wait for next command */ + eeprom_93c.state = WAIT_STANDBY; + break; + } + + default: + { + /* special command */ + switch ((eeprom_93c.opcode >> 4) & 3) + { + case 1: + { + /* WRITE ALL */ + eeprom_93c.buffer = 0; + eeprom_93c.cycles = 0; + eeprom_93c.state = WRITE_WORD; + break; + } + + case 2: + { + /* ERASE ALL */ + if (eeprom_93c.we) + { + memset(sram.sram, 0xFF, 128); + } + + /* wait for next command */ + eeprom_93c.state = WAIT_STANDBY; + break; + } + + default: + { + /* WRITE ENABLE/DISABLE */ + eeprom_93c.we = (eeprom_93c.opcode >> 4) & 1; + + /* wait for next command */ + eeprom_93c.state = WAIT_STANDBY; + break; + } + } + break; + } + } + } + break; + } + + case WRITE_WORD: + { + /* 16-bit data buffer */ + eeprom_93c.buffer |= ((data >> BIT_DATA) & 1) << (15 - eeprom_93c.cycles); + eeprom_93c.cycles++; + + if (eeprom_93c.cycles == 16) + { + /* check EEPROM write protection */ + if (eeprom_93c.we) + { + if (eeprom_93c.opcode & 0x40) + { + /* write one word */ + *(uint16 *)(sram.sram + ((eeprom_93c.opcode & 0x3F) << 1)) = eeprom_93c.buffer; + } + else + { + /* write 64 words */ + int i; + for (i=0; i<64; i++) + { + *(uint16 *)(sram.sram + (i << 1)) = eeprom_93c.buffer; + + } + } + } + + /* wait for next command */ + eeprom_93c.state = WAIT_STANDBY; + } + break; + } + + case READ_WORD: + { + /* set DATA OUT */ + eeprom_93c.data = ((eeprom_93c.buffer >> (15 - eeprom_93c.cycles)) & 1); + eeprom_93c.cycles++; + + if (eeprom_93c.cycles == 16) + { + /* read next word (93C46B) */ + eeprom_93c.opcode++; + eeprom_93c.cycles = 0; + eeprom_93c.buffer = *(uint16 *)(sram.sram + ((eeprom_93c.opcode & 0x3F) << 1)); + } + break; + } + + default: + { + /* wait for STANDBY mode */ + break; + } + } + } + } + else + { + /* CS HIGH->LOW transition */ + if (eeprom_93c.cs) + { + /* standby mode */ + eeprom_93c.data = 1; + eeprom_93c.state = WAIT_START; + } + } + + /* Update input lines */ + eeprom_93c.cs = (data >> BIT_CS) & 1; + eeprom_93c.clk = (data >> BIT_CLK) & 1; +} + +unsigned char eeprom_93c_read(void) +{ + return ((eeprom_93c.cs << BIT_CS) | (eeprom_93c.data << BIT_DATA) | (1 << BIT_CLK)); +} + diff --git a/genplus-gx/core/cart_hw/eeprom_93c.h b/genplus-gx/core/cart_hw/eeprom_93c.h new file mode 100644 index 0000000000..6c4e6e3f04 --- /dev/null +++ b/genplus-gx/core/cart_hw/eeprom_93c.h @@ -0,0 +1,72 @@ +/**************************************************************************** + * Genesis Plus + * Microwire Serial EEPROM (93C46 only) support + * + * Copyright (C) 2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _EEPROM_93C_H_ +#define _EEPROM_93C_H_ + +typedef enum +{ + WAIT_STANDBY, + WAIT_START, + GET_OPCODE, + WRITE_WORD, + READ_WORD +} T_STATE_93C; + +typedef struct +{ + uint8 enabled; /* 1: chip enabled */ + uint8 cs; /* CHIP SELECT line state */ + uint8 clk; /* CLK line state */ + uint8 data; /* DATA OUT line state */ + uint8 cycles; /* current operation cycle */ + uint8 we; /* 1: write enabled */ + uint8 opcode; /* 8-bit opcode + address */ + uint16 buffer; /* 16-bit data buffer */ + T_STATE_93C state; /* current operation state */ +} T_EEPROM_93C; + +/* global variables */ +extern T_EEPROM_93C eeprom_93c; + +/* Function prototypes */ +extern void eeprom_93c_init(); +extern void eeprom_93c_write(unsigned char data); +extern unsigned char eeprom_93c_read(void); + +#endif diff --git a/genplus-gx/core/cart_hw/eeprom_i2c.c b/genplus-gx/core/cart_hw/eeprom_i2c.c new file mode 100644 index 0000000000..12c4bdd466 --- /dev/null +++ b/genplus-gx/core/cart_hw/eeprom_i2c.c @@ -0,0 +1,621 @@ +/**************************************************************************** + * Genesis Plus + * I2C Serial EEPROM (24Cxx) support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +#define GAME_CNT 28 + +/* this defines the type of EEPROM inside the game cartridge as Backup RAM + * + * Here are some notes from 8BitWizard (http://www.spritesmind.net/_GenDev/forum): + * + * Mode 1 (7-bit) - the chip takes a single byte with a 7-bit memory address and a R/W bit (24C01) + * Mode 2 (8-bit) - the chip takes a 7-bit device address and R/W bit followed by an 8-bit memory address; + * the device address may contain up to three more memory address bits (24C01 - 24C16). + * You can also string eight 24C01, four 24C02, two 24C08, or various combinations, set their address config lines correctly, + * and the result appears exactly the same as a 24C16 + * Mode 3 (16-bit) - the chip takes a 7-bit device address and R/W bit followed by a 16-bit memory address (24C32 and larger) + * + * Also, while most 24Cxx are addressed at 200000-2FFFFF, I have found two different ways of mapping the control lines. + * EA uses SDA on D7 (read/write) and SCL on D6 (write only), and I have found boards using different mapping (I think Accolade) + * which uses D1-read=SDA, D0-write=SDA, D1-write=SCL. Accolade also has a custom-chip mapper which may even use a third method. + */ + +typedef struct +{ + uint8 address_bits; /* number of bits needed to address memory: 7, 8 or 16 */ + uint16 size_mask; /* depends on the max size of the memory (in bytes) */ + uint16 pagewrite_mask; /* depends on the maximal number of bytes that can be written in a single write cycle */ + uint32 sda_in_adr; /* 68000 memory address mapped to SDA_IN */ + uint32 sda_out_adr; /* 68000 memory address mapped to SDA_OUT */ + uint32 scl_adr; /* 68000 memory address mapped to SCL */ + uint8 sda_in_bit; /* bit offset for SDA_IN */ + uint8 sda_out_bit; /* bit offset for SDA_OUT */ + uint8 scl_bit; /* bit offset for SCL */ +} T_CONFIG_I2C; + +typedef enum +{ + STAND_BY = 0, + WAIT_STOP, + GET_SLAVE_ADR, + GET_WORD_ADR_7BITS, + GET_WORD_ADR_HIGH, + GET_WORD_ADR_LOW, + WRITE_DATA, + READ_DATA +} T_STATE_I2C; + +typedef struct +{ + uint8 sda; /* current /SDA line state */ + uint8 scl; /* current /SCL line state */ + uint8 old_sda; /* previous /SDA line state */ + uint8 old_scl; /* previous /SCL line state */ + uint8 cycles; /* current operation cycle number (0-9) */ + uint8 rw; /* operation type (1:READ, 0:WRITE) */ + uint16 slave_mask; /* device address (shifted by the memory address width)*/ + uint16 word_address; /* memory address */ + T_STATE_I2C state; /* current operation state */ + T_CONFIG_I2C config; /* EEPROM characteristics for this game */ +} T_EEPROM_I2C; + +typedef struct +{ + char game_id[16]; + uint16 chk; + T_CONFIG_I2C config; +} T_GAME_ENTRY; + +static const T_GAME_ENTRY database[GAME_CNT] = +{ + /* ACCLAIM mappers */ + /* 24C02 (old mapper) */ + {{"T-081326" }, 0, {8, 0xFF, 0xFF, 0x200001, 0x200001, 0x200001, 0, 1, 1}}, /* NBA Jam (UE) */ + {{"T-81033" }, 0, {8, 0xFF, 0xFF, 0x200001, 0x200001, 0x200001, 0, 1, 1}}, /* NBA Jam (J) */ + /* 24C02 */ + {{"T-081276" }, 0, {8, 0xFF, 0xFF, 0x200001, 0x200001, 0x200000, 0, 0, 0}}, /* NFL Quarterback Club */ + /* 24C04 */ + {{"T-81406" }, 0, {8, 0x1FF, 0x1FF, 0x200001, 0x200001, 0x200000, 0, 0, 0}}, /* NBA Jam TE */ + /* 24C16 */ + {{"T-081586" }, 0, {8, 0x7FF, 0x7FF, 0x200001, 0x200001, 0x200000, 0, 0, 0}}, /* NFL Quarterback Club '96 */ + /* 24C65 */ + {{"T-81576" }, 0, {16, 0x1FFF, 0x1FFF, 0x200001, 0x200001, 0x200000, 0, 0, 0}}, /* College Slam */ + {{"T-81476" }, 0, {16, 0x1FFF, 0x1FFF, 0x200001, 0x200001, 0x200000, 0, 0, 0}}, /* Frank Thomas Big Hurt Baseball */ + + /* EA mapper (X24C01 only) */ + {{"T-50176" }, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 7, 7, 6}}, /* Rings of Power */ + {{"T-50396" }, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 7, 7, 6}}, /* NHLPA Hockey 93 */ + {{"T-50446" }, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 7, 7, 6}}, /* John Madden Football 93 */ + {{"T-50516" }, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 7, 7, 6}}, /* John Madden Football 93 (Championship Ed.) */ + {{"T-50606" }, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 7, 7, 6}}, /* Bill Walsh College Football */ + + /* SEGA mapper (X24C01 only) */ + {{"T-12046" }, 0xAD23, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 0, 0, 1}}, /* Megaman - The Wily Wars */ + {{"T-12053" }, 0xEA80, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 0, 0, 1}}, /* Rockman Mega World [Alt] */ + {{"MK-1215" }, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 0, 0, 1}}, /* Evander 'Real Deal' Holyfield's Boxing */ + {{"MK-1228" }, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 0, 0, 1}}, /* Greatest Heavyweights of the Ring (U) */ + {{"G-5538" }, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 0, 0, 1}}, /* Greatest Heavyweights of the Ring (J) */ + {{"PR-1993" }, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 0, 0, 1}}, /* Greatest Heavyweights of the Ring (E) */ + {{"G-4060" }, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 0, 0, 1}}, /* Wonderboy in Monster World */ + {{"00001211-00"}, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 0, 0, 1}}, /* Sports Talk Baseball */ + {{"00004076-00"}, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 0, 0, 1}}, /* Honoo no Toukyuuji Dodge Danpei */ + {{"G-4524" }, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 0, 0, 1}}, /* Ninja Burai Densetsu */ + {{"00054503-00"}, 0, {7, 0x7F, 0x7F, 0x200001, 0x200001, 0x200001, 0, 0, 1}}, /* Game Toshokan */ + + /* CODEMASTERS mapper */ + /* 24C08 */ + {{"T-120106" }, 0, {8, 0x3FF, 0x3FF, 0x300000, 0x380001, 0x300000, 0, 7, 1}}, /* Brian Lara Cricket */ + {{"00000000-00"}, 0xCEE0, {8, 0x3FF, 0x3FF, 0x300000, 0x380001, 0x300000, 0, 7, 1}}, /* Micro Machines Military */ + /* 24C16 */ + {{"T-120096" }, 0, {8, 0x7FF, 0x7FF, 0x300000, 0x380001, 0x300000, 0, 7, 1}}, /* Micro Machines 2 - Turbo Tournament */ + {{"00000000-00"}, 0x2C41, {8, 0x7FF, 0x7FF, 0x300000, 0x380001, 0x300000, 0, 7, 1}}, /* Micro Machines Turbo Tournament 96 */ + /* 24C65 */ + {{"T-120146-50"}, 0, {16, 0x1FFF, 0x1FFF, 0x300000, 0x380001, 0x300000, 0, 7, 1}} /* Brian Lara Cricket 96, Shane Warne Cricket */ +}; + +static T_EEPROM_I2C eeprom_i2c; + +static unsigned int eeprom_i2c_read_byte(unsigned int address); +static unsigned int eeprom_i2c_read_word(unsigned int address); +static void eeprom_i2c_write_byte(unsigned int address, unsigned int data); +static void eeprom_i2c_write_word(unsigned int address, unsigned int data); + +void eeprom_i2c_init() +{ + int i = 0; + + /* initialize eeprom */ + memset(&eeprom_i2c, 0, sizeof(T_EEPROM_I2C)); + eeprom_i2c.sda = eeprom_i2c.old_sda = 1; + eeprom_i2c.scl = eeprom_i2c.old_scl = 1; + eeprom_i2c.state = STAND_BY; + + /* no eeprom by default */ + sram.custom = 0; + + /* look into game database */ + while (i> 16].read8 = eeprom_i2c_read_byte; + m68k.memory_map[eeprom_i2c.config.sda_out_adr >> 16].read16 = eeprom_i2c_read_word; + m68k.memory_map[eeprom_i2c.config.sda_in_adr >> 16].read8 = eeprom_i2c_read_byte; + m68k.memory_map[eeprom_i2c.config.sda_in_adr >> 16].read16 = eeprom_i2c_read_word; + m68k.memory_map[eeprom_i2c.config.scl_adr >> 16].write8 = eeprom_i2c_write_byte; + m68k.memory_map[eeprom_i2c.config.scl_adr >> 16].write16 = eeprom_i2c_write_word; + zbank_memory_map[eeprom_i2c.config.sda_out_adr >> 16].read = eeprom_i2c_read_byte; + zbank_memory_map[eeprom_i2c.config.sda_in_adr >> 16].read = eeprom_i2c_read_byte; + zbank_memory_map[eeprom_i2c.config.scl_adr >> 16].write = eeprom_i2c_write_byte; + } +} + +INLINE void Detect_START() +{ + if (eeprom_i2c.old_scl && eeprom_i2c.scl) + { + if (eeprom_i2c.old_sda && !eeprom_i2c.sda) + { + eeprom_i2c.cycles = 0; + eeprom_i2c.slave_mask = 0; + if (eeprom_i2c.config.address_bits == 7) + { + eeprom_i2c.word_address = 0; + eeprom_i2c.state = GET_WORD_ADR_7BITS; + } + else eeprom_i2c.state = GET_SLAVE_ADR; + } + } +} + +INLINE void Detect_STOP() +{ + if (eeprom_i2c.old_scl && eeprom_i2c.scl) + { + if (!eeprom_i2c.old_sda && eeprom_i2c.sda) + { + eeprom_i2c.state = STAND_BY; + } + } +} + +static void eeprom_i2c_update(void) +{ + /* EEPROM current state */ + switch (eeprom_i2c.state) + { + /* Standby Mode */ + case STAND_BY: + { + Detect_START(); + Detect_STOP(); + break; + } + + /* Suspended Mode */ + case WAIT_STOP: + { + Detect_STOP(); + break; + } + + /* Get Word Address 7 bits: MODE-1 only (24C01) + * and R/W bit + */ + case GET_WORD_ADR_7BITS: + { + Detect_START(); + Detect_STOP(); + + /* look for SCL LOW to HIGH transition */ + if (!eeprom_i2c.old_scl && eeprom_i2c.scl) + { + if (eeprom_i2c.cycles == 0) eeprom_i2c.cycles ++; + } + + + /* look for SCL HIGH to LOW transition */ + if (eeprom_i2c.old_scl && !eeprom_i2c.scl && (eeprom_i2c.cycles > 0)) + { + if (eeprom_i2c.cycles < 8) + { + eeprom_i2c.word_address |= (eeprom_i2c.old_sda << (7 - eeprom_i2c.cycles)); + } + else if (eeprom_i2c.cycles == 8) + { + eeprom_i2c.rw = eeprom_i2c.old_sda; + } + else + { /* ACK CYCLE */ + eeprom_i2c.cycles = 0; + eeprom_i2c.word_address &= eeprom_i2c.config.size_mask; + eeprom_i2c.state = eeprom_i2c.rw ? READ_DATA : WRITE_DATA; + } + + eeprom_i2c.cycles ++; + } + break; + } + + /* Get Slave Address (3bits) : MODE-2 & MODE-3 only (24C01 - 24C512) (0-3bits, depending on the array size) + * or/and Word Address MSB: MODE-2 only (24C04 - 24C16) (0-3bits, depending on the array size) + * and R/W bit + */ + case GET_SLAVE_ADR: + { + Detect_START(); + Detect_STOP(); + + /* look for SCL LOW to HIGH transition */ + if (!eeprom_i2c.old_scl && eeprom_i2c.scl) + { + if (eeprom_i2c.cycles == 0) eeprom_i2c.cycles ++; + } + + /* look for SCL HIGH to LOW transition */ + if (eeprom_i2c.old_scl && !eeprom_i2c.scl && (eeprom_i2c.cycles > 0)) + { + if ((eeprom_i2c.cycles > 4) && (eeprom_i2c.cycles <8)) + { + if ((eeprom_i2c.config.address_bits == 16) || + (eeprom_i2c.config.size_mask < (1 << (15 - eeprom_i2c.cycles)))) + { + /* this is a SLAVE ADDRESS bit */ + eeprom_i2c.slave_mask |= (eeprom_i2c.old_sda << (7 - eeprom_i2c.cycles)); + } + else + { + /* this is a WORD ADDRESS high bit */ + if (eeprom_i2c.old_sda) eeprom_i2c.word_address |= (1 << (15 - eeprom_i2c.cycles)); + else eeprom_i2c.word_address &= ~(1 << (15 - eeprom_i2c.cycles)); + } + } + else if (eeprom_i2c.cycles == 8) eeprom_i2c.rw = eeprom_i2c.old_sda; + else if (eeprom_i2c.cycles > 8) + { + /* ACK CYCLE */ + eeprom_i2c.cycles = 0; + if (eeprom_i2c.config.address_bits == 16) + { + /* two ADDRESS bytes */ + eeprom_i2c.state = eeprom_i2c.rw ? READ_DATA : GET_WORD_ADR_HIGH; + eeprom_i2c.slave_mask <<= 16; + } + else + { + /* one ADDRESS byte */ + eeprom_i2c.state = eeprom_i2c.rw ? READ_DATA : GET_WORD_ADR_LOW; + eeprom_i2c.slave_mask <<= 8; + } + } + + eeprom_i2c.cycles ++; + } + break; + } + + /* Get Word Address MSB (4-8bits depending on the array size) + * MODE-3 only (24C32 - 24C512) + */ + case GET_WORD_ADR_HIGH: + { + Detect_START(); + Detect_STOP(); + + /* look for SCL HIGH to LOW transition */ + if (eeprom_i2c.old_scl && !eeprom_i2c.scl) + { + if (eeprom_i2c.cycles < 9) + { + if ((eeprom_i2c.config.size_mask + 1) < (1 << (17 - eeprom_i2c.cycles))) + { + /* ignored bit: slave mask should be right-shifted by one */ + eeprom_i2c.slave_mask >>= 1; + } + else + { + /* this is a WORD ADDRESS high bit */ + if (eeprom_i2c.old_sda) eeprom_i2c.word_address |= (1 << (16 - eeprom_i2c.cycles)); + else eeprom_i2c.word_address &= ~(1 << (16 - eeprom_i2c.cycles)); + } + + eeprom_i2c.cycles ++; + } + else + { + /* ACK CYCLE */ + eeprom_i2c.cycles = 1; + eeprom_i2c.state = GET_WORD_ADR_LOW; + } + } + break; + } + + /* Get Word Address LSB: 7bits (24C01) or 8bits (24C02-24C512) + * MODE-2 and MODE-3 only (24C01 - 24C512) + */ + case GET_WORD_ADR_LOW: + { + Detect_START(); + Detect_STOP(); + + /* look for SCL HIGH to LOW transition */ + if (eeprom_i2c.old_scl && !eeprom_i2c.scl) + { + if (eeprom_i2c.cycles < 9) + { + if ((eeprom_i2c.config.size_mask + 1) < (1 << (9 - eeprom_i2c.cycles))) + { + /* ignored bit (X24C01): slave mask should be right-shifted by one */ + eeprom_i2c.slave_mask >>= 1; + } + else + { + /* this is a WORD ADDRESS high bit */ + if (eeprom_i2c.old_sda) eeprom_i2c.word_address |= (1 << (8 - eeprom_i2c.cycles)); + else eeprom_i2c.word_address &= ~(1 << (8 - eeprom_i2c.cycles)); + } + + eeprom_i2c.cycles ++; + } + else + { + /* ACK CYCLE */ + eeprom_i2c.cycles = 1; + eeprom_i2c.word_address &= eeprom_i2c.config.size_mask; + eeprom_i2c.state = WRITE_DATA; + } + } + break; + } + + /* + * Read Cycle + */ + case READ_DATA: + { + Detect_START(); + Detect_STOP(); + + /* look for SCL HIGH to LOW transition */ + if (eeprom_i2c.old_scl && !eeprom_i2c.scl) + { + if (eeprom_i2c.cycles < 9) eeprom_i2c.cycles ++; + else + { + eeprom_i2c.cycles = 1; + + /* ACK not received */ + if (eeprom_i2c.old_sda) eeprom_i2c.state = WAIT_STOP; + } + } + break; + } + + /* + * Write Cycle + */ + case WRITE_DATA: + { + Detect_START(); + Detect_STOP(); + + /* look for SCL HIGH to LOW transition */ + if (eeprom_i2c.old_scl && !eeprom_i2c.scl) + { + if (eeprom_i2c.cycles < 9) + { + /* Write DATA bits (max 64kBytes) */ + uint16 sram_address = (eeprom_i2c.slave_mask | eeprom_i2c.word_address) & 0xFFFF; + if (eeprom_i2c.old_sda) sram.sram[sram_address] |= (1 << (8 - eeprom_i2c.cycles)); + else sram.sram[sram_address] &= ~(1 << (8 - eeprom_i2c.cycles)); + + if (eeprom_i2c.cycles == 8) + { + /* WORD ADDRESS is incremented (roll up at maximum pagesize) */ + eeprom_i2c.word_address = (eeprom_i2c.word_address & (0xFFFF - eeprom_i2c.config.pagewrite_mask)) | + ((eeprom_i2c.word_address + 1) & eeprom_i2c.config.pagewrite_mask); + } + + eeprom_i2c.cycles ++; + } + else eeprom_i2c.cycles = 1; /* ACK cycle */ + } + break; + } + } + + eeprom_i2c.old_scl = eeprom_i2c.scl; + eeprom_i2c.old_sda = eeprom_i2c.sda; +} + +static unsigned char eeprom_i2c_out(void) +{ + uint8 sda_out = eeprom_i2c.sda; + + /* EEPROM state */ + switch (eeprom_i2c.state) + { + case READ_DATA: + { + if (eeprom_i2c.cycles < 9) + { + /* Return DATA bits (max 64kBytes) */ + uint16 sram_address = (eeprom_i2c.slave_mask | eeprom_i2c.word_address) & 0xffff; + sda_out = (sram.sram[sram_address] >> (8 - eeprom_i2c.cycles)) & 1; + + if (eeprom_i2c.cycles == 8) + { + /* WORD ADDRESS is incremented (roll up at maximum array size) */ + eeprom_i2c.word_address ++; + eeprom_i2c.word_address &= eeprom_i2c.config.size_mask; + } + } + break; + } + + case GET_WORD_ADR_7BITS: + case GET_SLAVE_ADR: + case GET_WORD_ADR_HIGH: + case GET_WORD_ADR_LOW: + case WRITE_DATA: + { + if (eeprom_i2c.cycles == 9) sda_out = 0; + break; + } + + default: + { + break; + } + } + + return (sda_out << eeprom_i2c.config.sda_out_bit); +} + +static unsigned int eeprom_i2c_read_byte(unsigned int address) +{ + if (address == eeprom_i2c.config.sda_out_adr) + { + return eeprom_i2c_out(); + } + + return READ_BYTE(cart.rom, address); +} + +static unsigned int eeprom_i2c_read_word(unsigned int address) +{ + if (address == eeprom_i2c.config.sda_out_adr) + { + return (eeprom_i2c_out() << 8); + } + + if (address == (eeprom_i2c.config.sda_out_adr ^ 1)) + { + return eeprom_i2c_out(); + } + + return *(uint16 *)(cart.rom + address); +} + +static void eeprom_i2c_write_byte(unsigned int address, unsigned int data) +{ + int do_update = 0; + + if (address == eeprom_i2c.config.sda_in_adr) + { + eeprom_i2c.sda = (data >> eeprom_i2c.config.sda_in_bit) & 1; + do_update = 1; + } + + if (address == eeprom_i2c.config.scl_adr) + { + eeprom_i2c.scl = (data >> eeprom_i2c.config.scl_bit) & 1; + do_update = 1; + } + + if (do_update) + { + eeprom_i2c_update(); + return; + } + + m68k_unused_8_w(address, data); +} + +static void eeprom_i2c_write_word(unsigned int address, unsigned int data) +{ + int do_update = 0; + + if (address == eeprom_i2c.config.sda_in_adr) + { + eeprom_i2c.sda = (data >> (8 + eeprom_i2c.config.sda_in_bit)) & 1; + do_update = 1; + } + else if (address == (eeprom_i2c.config.sda_in_adr ^1)) + { + eeprom_i2c.sda = (data >> eeprom_i2c.config.sda_in_bit) & 1; + do_update = 1; + } + + if (address == eeprom_i2c.config.scl_adr) + { + eeprom_i2c.scl = (data >> (8 + eeprom_i2c.config.scl_bit)) & 1; + do_update = 1; + } + else if (address == (eeprom_i2c.config.scl_adr ^1)) + { + eeprom_i2c.scl = (data >> eeprom_i2c.config.scl_bit) & 1; + do_update = 1; + } + + if (do_update) + { + eeprom_i2c_update(); + return; + } + + m68k_unused_16_w(address, data); +} diff --git a/genplus-gx/core/cart_hw/eeprom_i2c.h b/genplus-gx/core/cart_hw/eeprom_i2c.h new file mode 100644 index 0000000000..7c90497b60 --- /dev/null +++ b/genplus-gx/core/cart_hw/eeprom_i2c.h @@ -0,0 +1,45 @@ +/**************************************************************************** + * Genesis Plus + * I2C Serial EEPROM (24Cxx) support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _EEPROM_I2C_H_ +#define _EEPROM_I2C_H_ + +/* Function prototypes */ +extern void eeprom_i2c_init(); + +#endif diff --git a/genplus-gx/core/cart_hw/eeprom_spi.c b/genplus-gx/core/cart_hw/eeprom_spi.c new file mode 100644 index 0000000000..c913e9c113 --- /dev/null +++ b/genplus-gx/core/cart_hw/eeprom_spi.c @@ -0,0 +1,358 @@ +/**************************************************************************** + * Genesis Plus + * SPI Serial EEPROM (25xxx/95xxx) support + * + * Copyright (C) 2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +/* max supported size 64KB (25x512/95x512) */ +#define SIZE_MASK 0xffff +#define PAGE_MASK 0x7f + +/* hard-coded board implementation (!WP pin not used) */ +#define BIT_DATA (0) +#define BIT_CLK (1) +#define BIT_HOLD (2) +#define BIT_CS (3) + +typedef enum +{ + STANDBY, + GET_OPCODE, + GET_ADDRESS, + WRITE_BYTE, + READ_BYTE +} T_STATE_SPI; + +typedef struct +{ + uint8 cs; /* !CS line state */ + uint8 clk; /* SCLK line state */ + uint8 out; /* SO line state */ + uint8 status; /* status register */ + uint8 opcode; /* 8-bit opcode */ + uint8 buffer; /* 8-bit data buffer */ + uint16 addr; /* 16-bit address */ + uint32 cycles; /* current operation cycle */ + T_STATE_SPI state; /* current operation state */ +} T_EEPROM_SPI; + +static T_EEPROM_SPI spi_eeprom; + +void eeprom_spi_init() +{ + /* reset eeprom state */ + memset(&spi_eeprom, 0, sizeof(T_EEPROM_SPI)); + spi_eeprom.out = 1; + spi_eeprom.state = GET_OPCODE; + + /* enable backup RAM */ + sram.custom = 2; + sram.on = 1; +} + +void eeprom_spi_write(unsigned char data) +{ + /* Make sure !HOLD is high */ + if (data & (1 << BIT_HOLD)) + { + /* Check !CS state */ + if (data & (1 << BIT_CS)) + { + /* !CS high -> end of current operation */ + spi_eeprom.cycles = 0; + spi_eeprom.out = 1; + spi_eeprom.opcode = 0; + spi_eeprom.state = GET_OPCODE; + } + else + { + /* !CS low -> process current operation */ + switch (spi_eeprom.state) + { + case GET_OPCODE: + { + /* latch data on CLK positive edge */ + if ((data & (1 << BIT_CLK)) && !spi_eeprom.clk) + { + /* 8-bit opcode buffer */ + spi_eeprom.opcode |= ((data >> BIT_DATA) & 1); + spi_eeprom.cycles++; + + /* last bit ? */ + if (spi_eeprom.cycles == 8) + { + /* reset cycles count */ + spi_eeprom.cycles = 0; + + /* Decode instruction */ + switch (spi_eeprom.opcode) + { + case 0x01: + { + /* WRITE STATUS */ + spi_eeprom.buffer = 0; + spi_eeprom.state = WRITE_BYTE; + break; + } + + case 0x02: + { + /* WRITE BYTE */ + spi_eeprom.addr = 0; + spi_eeprom.state = GET_ADDRESS; + break; + } + + case 0x03: + { + /* READ BYTE */ + spi_eeprom.addr = 0; + spi_eeprom.state = GET_ADDRESS; + break; + } + + case 0x04: + { + /* WRITE DISABLE */ + spi_eeprom.status &= ~0x02; + spi_eeprom.state = STANDBY; + break; + } + + case 0x05: + { + /* READ STATUS */ + spi_eeprom.buffer = spi_eeprom.status; + spi_eeprom.state = READ_BYTE; + break; + } + + case 0x06: + { + /* WRITE ENABLE */ + spi_eeprom.status |= 0x02; + spi_eeprom.state = STANDBY; + break; + } + + default: + { + /* specific instructions (not supported) */ + spi_eeprom.state = STANDBY; + break; + } + } + } + else + { + /* shift opcode value */ + spi_eeprom.opcode = spi_eeprom.opcode << 1; + } + } + break; + } + + case GET_ADDRESS: + { + /* latch data on CLK positive edge */ + if ((data & (1 << BIT_CLK)) && !spi_eeprom.clk) + { + /* 16-bit address */ + spi_eeprom.addr |= ((data >> BIT_DATA) & 1); + spi_eeprom.cycles++; + + /* last bit ? */ + if (spi_eeprom.cycles == 16) + { + /* reset cycles count */ + spi_eeprom.cycles = 0; + + /* mask unused address bits */ + spi_eeprom.addr &= SIZE_MASK; + + /* operation type */ + if (spi_eeprom.opcode & 0x01) + { + /* READ operation */ + spi_eeprom.buffer = sram.sram[spi_eeprom.addr]; + spi_eeprom.state = READ_BYTE; + } + else + { + /* WRITE operation */ + spi_eeprom.buffer = 0; + spi_eeprom.state = WRITE_BYTE; + } + } + else + { + /* shift address value */ + spi_eeprom.addr = spi_eeprom.addr << 1; + } + } + break; + } + + case WRITE_BYTE: + { + /* latch data on CLK positive edge */ + if ((data & (1 << BIT_CLK)) && !spi_eeprom.clk) + { + /* 8-bit data buffer */ + spi_eeprom.buffer |= ((data >> BIT_DATA) & 1); + spi_eeprom.cycles++; + + /* last bit ? */ + if (spi_eeprom.cycles == 8) + { + /* reset cycles count */ + spi_eeprom.cycles = 0; + + /* write data to destination */ + if (spi_eeprom.opcode & 0x01) + { + /* update status register */ + spi_eeprom.status = (spi_eeprom.status & 0x02) | (spi_eeprom.buffer & 0x0c); + + /* wait for operation end */ + spi_eeprom.state = STANDBY; + } + else + { + /* Memory Array (write-protected) */ + if (spi_eeprom.status & 2) + { + /* check array protection bits (BP0, BP1) */ + switch ((spi_eeprom.status >> 2) & 0x03) + { + case 0x01: + { + /* $C000-$FFFF (sector #3) is protected */ + if (spi_eeprom.addr < 0xC000) + { + sram.sram[spi_eeprom.addr] = spi_eeprom.buffer; + } + break; + } + + case 0x02: + { + /* $8000-$FFFF (sectors #2 and #3) is protected */ + if (spi_eeprom.addr < 0x8000) + { + sram.sram[spi_eeprom.addr] = spi_eeprom.buffer; + } + break; + } + + case 0x03: + { + /* $0000-$FFFF (all sectors) is protected */ + break; + } + + default: + { + /* no sectors protected */ + sram.sram[spi_eeprom.addr] = spi_eeprom.buffer; + break; + } + } + } + + /* reset data buffer */ + spi_eeprom.buffer = 0; + + /* increase array address (sequential writes are limited within the same page) */ + spi_eeprom.addr = (spi_eeprom.addr & ~PAGE_MASK) | ((spi_eeprom.addr + 1) & PAGE_MASK); + } + } + else + { + /* shift data buffer value */ + spi_eeprom.buffer = spi_eeprom.buffer << 1; + } + } + break; + } + + case READ_BYTE: + { + /* output data on CLK positive edge */ + if ((data & (1 << BIT_CLK)) && !spi_eeprom.clk) + { + /* read out bits */ + spi_eeprom.out = (spi_eeprom.buffer >> (7 - spi_eeprom.cycles)) & 1; + spi_eeprom.cycles++; + + /* last bit ? */ + if (spi_eeprom.cycles == 8) + { + /* reset cycles count */ + spi_eeprom.cycles = 0; + + /* read from memory array ? */ + if (spi_eeprom.opcode == 0x03) + { + /* read next array byte */ + spi_eeprom.addr = (spi_eeprom.addr + 1) & SIZE_MASK; + spi_eeprom.buffer = sram.sram[spi_eeprom.addr]; + } + } + } + break; + } + + default: + { + /* wait for !CS low->high transition */ + break; + } + } + } + } + + /* update input lines */ + spi_eeprom.cs = (data >> BIT_CS) & 1; + spi_eeprom.clk = (data >> BIT_CLK) & 1; +} + +unsigned int eeprom_spi_read(unsigned int address) +{ + return (spi_eeprom.out << BIT_DATA); +} + diff --git a/genplus-gx/core/cart_hw/eeprom_spi.h b/genplus-gx/core/cart_hw/eeprom_spi.h new file mode 100644 index 0000000000..b1287bdd89 --- /dev/null +++ b/genplus-gx/core/cart_hw/eeprom_spi.h @@ -0,0 +1,47 @@ +/**************************************************************************** + * Genesis Plus + * SPI Serial EEPROM (25XX512 only) support + * + * Copyright (C) 2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _EEPROM_SPI_H_ +#define _EEPROM_SPI_H_ + +/* Function prototypes */ +extern void eeprom_spi_init(); +extern void eeprom_spi_write(unsigned char data); +extern unsigned int eeprom_spi_read(unsigned int address); + +#endif diff --git a/genplus-gx/core/cart_hw/ggenie.c b/genplus-gx/core/cart_hw/ggenie.c new file mode 100644 index 0000000000..e6d82c1713 --- /dev/null +++ b/genplus-gx/core/cart_hw/ggenie.c @@ -0,0 +1,283 @@ +/**************************************************************************** + * Genesis Plus + * Game Genie Hardware emulation + * + * Copyright (C) 2009-2011 Eke-Eke (Genesis Plus GX) + * + * Based on documentation from Charles McDonald + * (http://cgfm2.emuviews.com/txt/genie.txt) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +static struct +{ + uint8 enabled; + uint8 *rom; + uint16 regs[0x20]; + uint16 old[6]; + uint16 data[6]; + uint32 addr[6]; +} ggenie; + +static unsigned int ggenie_read_byte(unsigned int address); +static unsigned int ggenie_read_word(unsigned int address); +static void ggenie_write_byte(unsigned int address, unsigned int data); +static void ggenie_write_word(unsigned int address, unsigned int data); +static void ggenie_write_regs(unsigned int offset, unsigned int data); + +void ggenie_init(void) +{ + int i; + FILE *f; + + memset(&ggenie,0,sizeof(ggenie)); + + /* Store Game Genie ROM (32k) above cartridge ROM + SRAM area */ + if (cart.romsize > 0x810000) return; + ggenie.rom = cart.rom + 0x810000; + + /* Open Game Genie ROM file */ + f = fopen(GG_ROM,"rb"); + if (f == NULL) return; + + /* Load ROM */ + for (i=0; i<0x8000; i+=0x1000) + { + fread(ggenie.rom + i, 0x1000, 1, f); + } + + /* Close ROM file */ + fclose(f); + +#ifdef LSB_FIRST + for (i=0; i<0x8000; i+=2) + { + /* Byteswap ROM */ + uint8 temp = ggenie.rom[i]; + ggenie.rom[i] = ggenie.rom[i+1]; + ggenie.rom[i+1] = temp; + } +#endif + + /* $0000-$7fff mirrored into $8000-$ffff */ + memcpy(ggenie.rom + 0x8000, ggenie.rom, 0x8000); + + /* set flag */ + ggenie.enabled = 1; +} + +void ggenie_shutdown(void) +{ + if (ggenie.enabled) + { + ggenie_switch(0); + ggenie.enabled = 0; + } +} + +void ggenie_reset(int hard) +{ + if (ggenie.enabled) + { + if (hard) + { + /* clear codes */ + ggenie_switch(0); + + /* reset internal state */ + memset(ggenie.regs,0,sizeof(ggenie.regs)); + memset(ggenie.old,0,sizeof(ggenie.old)); + memset(ggenie.data,0,sizeof(ggenie.data)); + memset(ggenie.addr,0,sizeof(ggenie.addr)); + } + + /* Game Genie ROM is mapped at $000000-$007fff */ + m68k.memory_map[0].base = ggenie.rom; + + /* Internal registers are mapped at $000000-$00001f */ + m68k.memory_map[0].write8 = ggenie_write_byte; + m68k.memory_map[0].write16 = ggenie_write_word; + + /* Disable registers reads */ + m68k.memory_map[0].read16 = NULL; + } +} + +void ggenie_switch(int enable) +{ + int i; + if (enable) + { + /* enable cheats */ + for (i=0; i<6; i++) + { + /* patch is enabled ? */ + if (ggenie.regs[0] & (1 << i)) + { + /* save old value and patch ROM if enabled */ + ggenie.old[i] = *(uint16 *)(cart.rom + ggenie.addr[i]); + *(uint16 *)(cart.rom + ggenie.addr[i]) = ggenie.data[i]; + } + } + } + else + { + /* disable cheats in reversed order in case the same address is used by multiple patches */ + for (i=5; i>=0; i--) + { + /* patch is enabled ? */ + if (ggenie.regs[0] & (1 << i)) + { + /* restore original ROM value */ + *(uint16 *)(cart.rom + ggenie.addr[i]) = ggenie.old[i]; + } + } + } +} + +static unsigned int ggenie_read_byte(unsigned int address) +{ + unsigned int data = ggenie.regs[(address >> 1) & 0x1f]; + return ((address & 1) ? (data & 0xff) : ((data >> 8) & 0xff)); +} + +static unsigned int ggenie_read_word(unsigned int address) +{ + return ggenie.regs[(address >> 1) & 0x1f]; +} + +static void ggenie_write_byte(unsigned int address, unsigned int data) +{ + /* Register offset */ + uint8 offset = (address >> 1) & 0x1f; + + /* /LWR and /UWR are used to decode writes */ + if (address & 1) + { + data = (ggenie.regs[offset] & 0xff00) | (data & 0xff); + } + else + { + data = (ggenie.regs[offset] & 0x00ff) | ((data & 0xff) << 8); + } + + /* Update internal register */ + ggenie_write_regs(offset,data); +} + +static void ggenie_write_word(unsigned int address, unsigned int data) +{ + /* Register offset */ + uint8 offset = (address >> 1) & 0x1f; + + /* Write internal register (full WORD) */ + ggenie_write_regs(offset,data); +} + +static void ggenie_write_regs(unsigned int offset, unsigned int data) +{ + /* update internal register */ + ggenie.regs[offset] = data; + + /* Mode Register */ + if (offset == 0) + { + /* MODE bit */ + if (data & 0x400) + { + /* $0000-$7ffff reads mapped to Cartridge ROM */ + m68k.memory_map[0].base = cart.rom; + m68k.memory_map[0].read8 = NULL; + m68k.memory_map[0].read16 = NULL; + } + else + { + /* $0000-$7ffff reads mapped to Game Genie ROM */ + m68k.memory_map[0].base = ggenie.rom; + m68k.memory_map[0].read8 = NULL; + m68k.memory_map[0].read16 = NULL; + + /* READ_ENABLE bit */ + if (data & 0x200) + { + /* $0000-$7ffff reads mapped to Game Genie Registers */ + /* code doing this should execute in RAM so we don't need to modify base address */ + m68k.memory_map[0].read8 = ggenie_read_byte; + m68k.memory_map[0].read16 = ggenie_read_word; + } + } + + /* LOCK bit */ + if (data & 0x100) + { + /* decode patch address (ROM area only)*/ + /* note: Charles's doc is wrong, first register holds bits 23-16 of patch address */ + ggenie.addr[0] = ((ggenie.regs[2] & 0x3f) << 16) | ggenie.regs[3]; + ggenie.addr[1] = ((ggenie.regs[5] & 0x3f) << 16) | ggenie.regs[6]; + ggenie.addr[2] = ((ggenie.regs[8] & 0x3f) << 16) | ggenie.regs[9]; + ggenie.addr[3] = ((ggenie.regs[11] & 0x3f) << 16) | ggenie.regs[12]; + ggenie.addr[4] = ((ggenie.regs[14] & 0x3f) << 16) | ggenie.regs[15]; + ggenie.addr[5] = ((ggenie.regs[17] & 0x3f) << 16) | ggenie.regs[18]; + + /* decode patch data */ + ggenie.data[0] = ggenie.regs[4]; + ggenie.data[1] = ggenie.regs[7]; + ggenie.data[2] = ggenie.regs[10]; + ggenie.data[3] = ggenie.regs[13]; + ggenie.data[4] = ggenie.regs[16]; + ggenie.data[5] = ggenie.regs[19]; + + /* disable internal registers */ + m68k.memory_map[0].write8 = m68k_unused_8_w; + m68k.memory_map[0].write16 = m68k_unused_16_w; + + /* patch ROM when GG program exits (LOCK bit set) */ + /* this is done here to handle patched program reads faster & more easily */ + /* on real HW, address decoding would be done on each reads */ + ggenie_switch(1); + } + else + { + m68k.memory_map[0].write8 = ggenie_write_byte; + m68k.memory_map[0].write16 = ggenie_write_word; + } + } + + /* RESET register */ + else if (offset == 1) + { + ggenie.regs[1] |= 1; + } +} diff --git a/genplus-gx/core/cart_hw/ggenie.h b/genplus-gx/core/cart_hw/ggenie.h new file mode 100644 index 0000000000..524c751434 --- /dev/null +++ b/genplus-gx/core/cart_hw/ggenie.h @@ -0,0 +1,51 @@ +/**************************************************************************** + * Genesis Plus + * Game Genie Hardware emulation + * + * Copyright (C) 2009-2011 Eke-Eke (Genesis Plus GX) + * + * Based on documentation from Charles McDonald + * (http://cgfm2.emuviews.com/txt/genie.txt) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _GGENIE_H_ +#define _GGENIE_H_ + +/* Function prototypes */ +extern void ggenie_init(void); +extern void ggenie_shutdown(void); +extern void ggenie_reset(int hard); +extern void ggenie_switch(int enable); + +#endif diff --git a/genplus-gx/core/cart_hw/md_cart.c b/genplus-gx/core/cart_hw/md_cart.c new file mode 100644 index 0000000000..c7ddf5850e --- /dev/null +++ b/genplus-gx/core/cart_hw/md_cart.c @@ -0,0 +1,1906 @@ +/**************************************************************************** + * Genesis Plus + * Mega Drive cartridge hardware support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Many cartridge protections were initially documented by Haze + * (http://haze.mameworld.info/) + * + * Realtec mapper was documented by TascoDeluxe + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "eeprom_i2c.h" +#include "eeprom_spi.h" +#include "gamepad.h" + +#define CART_CNT (55) + +/* Cart database entry */ +typedef struct +{ + uint16 chk_1; /* header checksum */ + uint16 chk_2; /* real checksum */ + uint8 bank_start; /* first mapped bank in $400000-$7fffff region */ + uint8 bank_end; /* last mapped bank in $400000-$7fffff region */ + cart_hw_t cart_hw; /* hardware description */ +} md_entry_t; + +/* Function prototypes */ +static void mapper_sega_w(uint32 data); +static void mapper_ssf2_w(uint32 address, uint32 data); +static void mapper_sf001_w(uint32 address, uint32 data); +static void mapper_sf002_w(uint32 address, uint32 data); +static void mapper_sf004_w(uint32 address, uint32 data); +static uint32 mapper_sf004_r(uint32 address); +static void mapper_t5740_w(uint32 address, uint32 data); +static uint32 mapper_t5740_r(uint32 address); +static uint32 mapper_smw_64_r(uint32 address); +static void mapper_smw_64_w(uint32 address, uint32 data); +static void mapper_realtec_w(uint32 address, uint32 data); +static void mapper_seganet_w(uint32 address, uint32 data); +static void mapper_32k_w(uint32 data); +static void mapper_64k_w(uint32 data); +static void mapper_64k_multi_w(uint32 address); +static uint32 mapper_radica_r(uint32 address); +static void default_time_w(uint32 address, uint32 data); +static void default_regs_w(uint32 address, uint32 data); +static uint32 default_regs_r(uint32 address); +static uint32 default_regs_r_16(uint32 address); +static uint32 custom_regs_r(uint32 address); +static void custom_regs_w(uint32 address, uint32 data); +static void custom_alt_regs_w(uint32 address, uint32 data); +static uint32 topshooter_r(uint32 address); +static void topshooter_w(uint32 address, uint32 data); +static uint32 tekken_regs_r(uint32 address); +static void tekken_regs_w(uint32 address, uint32 data); + +/* Games that need extra hardware emulation: + - copy protection device + - custom ROM banking device +*/ +static const md_entry_t rom_database[CART_CNT] = +{ +/* Funny World & Balloon Boy */ + {0x0000,0x06ab,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},1,0,NULL,NULL,NULL,mapper_realtec_w}}, +/* Whac-a-Critter */ + {0xffff,0xf863,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},1,0,NULL,NULL,NULL,mapper_realtec_w}}, +/* Earth Defense */ + {0xffff,0x44fb,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},1,0,NULL,NULL,NULL,mapper_realtec_w}}, + + +/* RADICA (Volume 1) (bad dump ?) */ + {0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,1,mapper_radica_r,NULL,NULL,NULL}}, +/* RADICA (Volume 1) */ + {0x24f4,0xfc84,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_radica_r,NULL,NULL,NULL}}, +/* RADICA (Volume 2) */ + {0x104f,0x32e9,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_radica_r,NULL,NULL,NULL}}, + + +/* Tenchi wo Kurau III: Sangokushi Gaiden - Chinese Fighter */ + {0x9490,0x8180,0x40,0x6f,{{0x00,0x00,0x00,0x00},{0xf0000c,0xf0000c,0xf0000c,0xf0000c},{0x400000,0x400004,0x400008,0x40000c},0,1,NULL,NULL,default_regs_r,custom_alt_regs_w}}, + + +/* Top Fighter */ + {0x4eb9,0x5d8b,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Soul Edge VS Samurai Spirits */ + {0x00ff,0x5d34,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Mulan */ + {0x0404,0x1b40,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Pocket Monsters II */ + {0x47f9,0x17e5,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Lion King 3 */ + {0x0000,0x507c,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Super King Kong 99 */ + {0x0000,0x7d6e,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Gunfight 3-in-1 */ + {0x0000,0x6ff8,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Pokemon Stadium */ + {0x0000,0x843c,0x70,0x7f,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,1,NULL,NULL,NULL,custom_regs_w}}, + + +/* Tekken 3 Special (original dump) (a bootleg version also exists, with patched protection & different boot routine which reads unused !TIME mapped area) */ + {0x0000,0xc2f0,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,NULL,tekken_regs_r,tekken_regs_w}}, + + +/* Lion King 2 */ + {0xffff,0x1d9b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Squirell King */ + {0x0000,0x8ec8,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Tiny Toon Adventures 3 */ + {0x2020,0xed9c,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Lian Huan Pao - Barver Battle Saga (registers accessed by Z80, related to sound engine ?) */ + {0x30b9,0x1c2a,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Shui Hu Zhuan (registers accessed by Z80, related to sound engine ?) */ + {0x6001,0x0211,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Feng Shen Ying Jie Chuan (registers accessed by Z80, related to sound engine ?) */ + {0xffff,0x5d98,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* (*) Shui Hu - Feng Yun Zhuan (patched ROM, unused registers) */ + {0x3332,0x872b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, + + +/* (*) Chao Ji Da Fu Weng (patched ROM, various words witten to register, long word also read from $7E0000, unknown banking hardware ?) */ + {0xa697,0xa697,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x000000,0x000000,0x000000},0,0,NULL,NULL,NULL,default_regs_w}}, + +/* (*) Aq Renkan Awa (patched ROM, ON/OFF bit sequence is written to register, unknown banking hardware ?) */ + {0x8104,0x0517,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400001,0x000000,0x000000,0x000000},0,0,NULL,NULL,NULL,default_regs_w}}, + + +/* (*) Tun Shi Tian Di III (patched ROM, unused register) */ + {0x0000,0x9c5e,0x40,0x40,{{0xab,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400046,0x000000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, + + +/* Ma Jiang Qing Ren - Ji Ma Jiang Zhi */ + {0x0000,0x7037,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x401000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Super Majon Club */ + {0x0000,0x3b95,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x401000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Feng Kuang Tao Hua Yuan (original version from Creaton Softec Inc) (a bootleg version also exists with patched protection and minor title screen variations) */ + {0x0000,0x9dc4,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x401000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, + + +/* (*) Jiu Ji Ma Jiang II - Ye Yan Bian (patched ROM, using expected register value - $0f - crashes the game) (uses 16-bits reads) */ + {0x0c44,0xba81,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x400006},0,0,NULL,NULL,default_regs_r_16,NULL}}, +/* 16 Zhang Ma Jiang (uses 16-bits reads) */ + {0xfb40,0x4bed,0x40,0x40,{{0x00,0xaa,0x00,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x400002,0x000000,0x400006},0,0,NULL,NULL,default_regs_r_16,NULL}}, +/* 16 Tiles Mahjong II (uses 16-bits reads) */ + {0xffff,0x0903,0x40,0x40,{{0x00,0x00,0xc9,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x400004,0x000000},0,0,NULL,NULL,default_regs_r_16,NULL}}, +/* Thunderbolt II (uses 16-bits reads) */ + {0x0000,0x1585,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r_16,NULL}}, + + +/* Super Bubble Bobble */ + {0x0000,0x16cd,0x40,0x40,{{0x55,0x0f,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Tenchi wo Kurau II - The Battle of Red Cliffs (Unl) */ + {0x0000,0xed61,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Huan Le Tao Qi Shu - Smart Mouse */ + {0x0000,0x1a28,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* (*) Hei Tao 2 - Super Big 2 (patched ROM, unused registers) */ + {0x0000,0x5843,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Mighty Morphin Power Rangers - The Fighting Edition */ + {0x0000,0x2288,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Elf Wor */ + {0x0080,0x3dba,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Ya-Se Chuanshuo */ + {0xffff,0xd472,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* 777 Casino (For first one, 0x55 works as well. Other values are never used so they are guessed from on other unlicensed games using similar mapper) */ + {0x0000,0xf8d9,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Wu Kong Wai Zhuan (original) (a bootleg version also exists, with patched protection & modified SRAM test routine ?) */ + {0x0000,0x19ff,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Soul Blade */ + {0x0000,0x0c5b,0x40,0x40,{{0x63,0x98,0xc9,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, + + +/* King of Fighter 98 */ + {0x0000,0xd0a0,0x48,0x4f,{{0x00,0x00,0xaa,0xf0},{0xffffff,0xffffff,0xfc0000,0xfc0000},{0x000000,0x000000,0x480000,0x4c0000},0,0,NULL,NULL,default_regs_r,NULL}}, + + +/* Rockman X3 (bootleg version ? two last register returned values are ignored, note that 0xaa/0x18 would work as well) */ + {0x0000,0x9d0e,0x40,0x40,{{0x0c,0x00,0xc9,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x400004,0x400006},0,0,default_regs_r,NULL,default_regs_r,NULL}}, + + +/* (*) Dragon Ball Final Bout (patched ROM, in original code, different switches occurs depending on returned value $00-$0f) */ + {0xc65a,0xc65a,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, +/* (*) Yang Jia Jiang - Yang Warrior Family (patched ROM, register value unused) */ + {0x0000,0x96b0,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, +/* Super Mario 2 1998 */ + {0xffff,0x0474,0x00,0x00,{{0x0a,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, +/* Super Mario World */ + {0x2020,0xb4eb,0x00,0x00,{{0x1c,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, + + +/* King of Fighter 99 */ + {0x0000,0x021e,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,custom_regs_r,default_regs_w,NULL,NULL}}, +/* Pocket Monster */ + {0xd6fc,0x1eb1,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,custom_regs_r,default_regs_w,NULL,NULL}}, +/* Pocket Monster (bootleg version ? two last register returned values are ignored & first register test has been modified) */ + {0xd6fc,0x6319,0x00,0x00,{{0x14,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,m68k_unused_8_w,NULL,NULL}}, +/* A Bug's Life (bootleg version ? two last register returned values are ignored & first register test has been modified ?) */ + {0x7f7f,0x2aad,0x00,0x00,{{0x28,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,m68k_unused_8_w,NULL,NULL}}, + + +/* Game no Kanzume Otokuyou */ + {0x0000,0xf9d1,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,mapper_seganet_w,NULL,NULL}}, + + +/* Top Shooter (arcade hardware) */ + {0xffff,0x3632,0x20,0x20,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,NULL,topshooter_r,topshooter_w}} +}; + + +/************************************************************ + Cart Hardware initialization +*************************************************************/ + +void md_cart_init(void) +{ + int i; + + /*************************************************************************************************************** + CARTRIDGE ROM MIRRORING + *************************************************************************************************************** + + MD Cartridge area is mapped to $000000-$3fffff: + + -> when accessing ROM, 68k address lines A1 to A21 can be used by the internal cartridge hardware to decode + full 4MB address range. + -> depending on ROM total size and additional decoding hardware, some address lines might be ignored, + resulting in ROM mirroring. + + Cartridges can use either 8-bits (x2) or 16-bits (x1, x2) Mask ROM chips, each chip size is a factor of 2 bytes: + + -> two 8-bits chips are equivalent to one 16-bits chip, no specific address decoding is required, needed + address lines are simply connected to each chip, upper address lines are ignored and data lines are + connected appropriately to each chip (D0-D7 to one chip, D8-D15 to the other one). + ROM is generally mirrored each N bytes where N=2^(k+1) is the total ROM size (ROM1+ROM2,ROM1+ROM2,...) + + -> one single 16-bits chip do not need specific address decoding, address lines are simply connected + depending on the ROM size, upper address lines being ignored. + ROM is generally mirrored each N bytes where N=2^k is the size of the ROM chip (ROM1,ROM1,ROM1,...) + + -> two 16-bits chips of the same size are equivalent to one chip of double size, address decoding generally + is the same except that specific hardware is used (one address line is generally used for chip selection, + lower ones being used to address the chips and upper ones being ignored). + ROM is generally mirrored each N bytes where N=2^(k+1) is the total ROM size (ROM1,ROM2,ROM1,ROM2,...) + + -> two 16-bits chips with different size are mapped differently. Address decoding is done the same way as + above (one address line used for chip selection) but the ignored & required address lines differ from + one chip to another, which makes ROM mirroring different. + ROM2 size is generally half of ROM1 size and upper half ignored (ROM1,ROM2,XXXX,ROM1,ROM2,XXXX,...) + + From the emulator point of view, we only need to distinguish 2 cases: + + 1/ total ROM size is a factor of 2: ROM is mirrored each 2^k bytes. + + 2/ total ROM size is not a factor of 2: ROM is padded up to 2^k then mirrored each 2^k bytes. + + ******************************************************************************************************************/ + + /* calculate nearest size with factor of 2 */ + unsigned int size = 0x10000; + while (cart.romsize > size) + size <<= 1; + + /* total ROM size is not a factor of 2 */ + /* TODO: handle all possible ROM configurations using cartridge database */ + if ((size < MAXROMSIZE) && (cart.romsize < size)) + { + /* ROM is padded up to 2^k bytes */ + memset(cart.rom + cart.romsize, 0xff, size - cart.romsize); + } + + /* Sonic & Knuckles */ + if (strstr(rominfo.international,"SONIC & KNUCKLES")) + { + /* disable ROM mirroring at $200000-$3fffff (normally mapped to external cartridge) */ + size = 0x400000; + } + + /* ROM is mirrored each 2^k bytes */ + cart.mask = size - 1; + + /********************************************** + DEFAULT CARTRIDGE MAPPING + ***********************************************/ + for (i=0; i<0x40; i++) + { + /* cartridge ROM */ + m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].read = NULL; + zbank_memory_map[i].write = zbank_unused_w; + } + + for (i=0x40; i<0x80; i++) + { + /* unused area */ + m68k.memory_map[i].base = cart.rom + (i<<16); + m68k.memory_map[i].read8 = m68k_read_bus_8; + m68k.memory_map[i].read16 = m68k_read_bus_16; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].read = zbank_unused_r; + zbank_memory_map[i].write = zbank_unused_w; + } + + /* support for Quackshot REV 01 (real) dump */ + if (strstr(rominfo.product,"00004054-01") && (cart.romsize == 0x80000)) + { + /* $000000-$0fffff: first 256K mirrored (A18 not connected to ROM chip, A19 not decoded) */ + for (i=0x00; i<0x10; i++) + { + /* $200000-$3fffff: mirror of $000000-$1fffff (A21 not decoded) */ + m68k.memory_map[i].base = m68k.memory_map[i + 0x20].base = cart.rom + ((i & 0x03) << 16); + } + + /* $100000-$1fffff: second 256K mirrored (A20 connected to ROM chip A18) */ + for (i=0x10; i<0x20; i++) + { + /* $200000-$3fffff: mirror of $000000-$1fffff (A21 not decoded) */ + m68k.memory_map[i].base = m68k.memory_map[i + 0x20].base = cart.rom + 0x40000 + ((i & 0x03) << 16); + } + } + + /********************************************** + BACKUP MEMORY + ***********************************************/ + sram_init(); + eeprom_i2c_init(); + + /* external SRAM */ + if (sram.on && !sram.custom) + { + /* disabled on startup if ROM is mapped in same area */ + if (cart.romsize <= sram.start) + { + /* initialize m68k bus handlers */ + m68k.memory_map[sram.start >> 16].base = sram.sram; + m68k.memory_map[sram.start >> 16].read8 = sram_read_byte; + m68k.memory_map[sram.start >> 16].read16 = sram_read_word; + m68k.memory_map[sram.start >> 16].write8 = sram_write_byte; + m68k.memory_map[sram.start >> 16].write16 = sram_write_word; + zbank_memory_map[sram.start >> 16].read = sram_read_byte; + zbank_memory_map[sram.start >> 16].write = sram_write_byte; + } + } + + /********************************************** + SVP CHIP + ***********************************************/ + svp = NULL; + if (strstr(rominfo.international,"Virtua Racing")) + { + svp_init(); + + m68k.memory_map[0x30].base = svp->dram; + m68k.memory_map[0x30].read16 = NULL; + m68k.memory_map[0x30].write16 = svp_write_dram; + + m68k.memory_map[0x31].base = svp->dram + 0x10000; + m68k.memory_map[0x31].read16 = NULL; + m68k.memory_map[0x31].write16 = svp_write_dram; + + m68k.memory_map[0x39].read16 = svp_read_cell_1; + m68k.memory_map[0x3a].read16 = svp_read_cell_2; + } + + /********************************************** + J-CART + ***********************************************/ + cart.special = 0; + if ((strstr(rominfo.product,"00000000") && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military */ + (strstr(rominfo.product,"00000000") && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */ + (strstr(rominfo.product,"00000000") && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */ + (strstr(rominfo.product,"00000000") && (rominfo.checksum == 0x2c41)) || /* Micro Machines 96 (bad) */ + (strstr(rominfo.product,"XXXXXXXX") && (rominfo.checksum == 0xdf39)) || /* Sampras Tennis 96 */ + (strstr(rominfo.product,"T-123456") && (rominfo.checksum == 0x1eae)) || /* Sampras Tennis 96 */ + (strstr(rominfo.product,"T-120066") && (rominfo.checksum == 0x16a4)) || /* Pete Sampras Tennis (1994)*/ + strstr(rominfo.product,"T-120096")) /* Micro Machines 2 */ + { + if (cart.romsize <= 0x380000) /* just to be sure (checksum might not be enough) */ + { + cart.special |= HW_J_CART; + + /* force port 1 setting */ + if (input.system[1] != SYSTEM_WAYPLAY) + { + old_system[1] = input.system[1]; + input.system[1] = SYSTEM_MD_GAMEPAD; + } + + /* extra connectors mapped at $38xxxx or $3Fxxxx */ + m68k.memory_map[0x38].read16 = jcart_read; + m68k.memory_map[0x38].write16 = jcart_write; + m68k.memory_map[0x3f].read16 = jcart_read; + m68k.memory_map[0x3f].write16 = jcart_write; + } + } + + /********************************************** + LOCK-ON + ***********************************************/ + + /* clear existing patches */ + ggenie_shutdown(); + areplay_shutdown(); + + /* initialize extra hardware */ + switch (config.lock_on) + { + case TYPE_GG: + { + ggenie_init(); + break; + } + + case TYPE_AR: + { + areplay_init(); + break; + } + + case TYPE_SK: + { + FILE *f; + + /* store S&K ROM above cartridge ROM (and before backup memory) */ + if (cart.romsize > 0x600000) break; + + /* load Sonic & Knuckles ROM (2 MB) */ + f = fopen(SK_ROM,"rb"); + if (!f) break; + for (i=0; i<0x200000; i+=0x1000) + { + fread(cart.rom + 0x600000 + i, 0x1000, 1, f); + } + fclose(f); + + /* load Sonic 2 UPMEM ROM (256 KB) */ + f = fopen(SK_UPMEM,"rb"); + if (!f) break; + for (i=0; i<0x40000; i+=0x1000) + { + fread(cart.rom + 0x900000 + i, 0x1000, 1, f); + } + fclose(f); + +#ifdef LSB_FIRST + for (i=0; i<0x200000; i+=2) + { + /* Byteswap ROM */ + uint8 temp = cart.rom[i + 0x600000]; + cart.rom[i + 0x600000] = cart.rom[i + 0x600000 + 1]; + cart.rom[i + 0x600000 + 1] = temp; + } + + for (i=0; i<0x40000; i+=2) + { + /* Byteswap ROM */ + uint8 temp = cart.rom[i + 0x900000]; + cart.rom[i + 0x900000] = cart.rom[i + 0x900000 + 1]; + cart.rom[i + 0x900000 + 1] = temp; + } +#endif + + /* $000000-$1FFFFF is mapped to S&K ROM */ + for (i=0x00; i<0x20; i++) + { + m68k.memory_map[i].base = cart.rom + 0x600000 + (i << 16); + } + + cart.special |= HW_LOCK_ON; + break; + } + + default: + { + break; + } + } + + /********************************************** + CARTRIDGE EXTRA HARDWARE + ***********************************************/ + memset(&cart.hw, 0, sizeof(cart.hw)); + + /* search for game into database */ + for (i=0; i 0x400000) + { + /* assume linear ROM mapper without bankswitching (max. 10MB) */ + for (i=0x40; i<0xA0; i++) + { + m68k.memory_map[i].base = cart.rom + (i<<16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + } + } + + /* default write handler for !TIME range ($A130xx)*/ + if (!cart.hw.time_w) + { + cart.hw.time_w = default_time_w; + } +} + +/* hardware that need to be reseted on power on */ +void md_cart_reset(int hard_reset) +{ + int i; + + /* reset cartridge mapping */ + if (cart.hw.bankshift) + { + for (i=0x00; i<0x40; i++) + { + m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); + } + } + + /* SVP chip */ + if (svp) + { + svp_reset(); + } + + /* Lock-ON */ + switch (config.lock_on) + { + case TYPE_GG: + { + ggenie_reset(hard_reset); + break; + } + + case TYPE_AR: + { + areplay_reset(hard_reset); + break; + } + + case TYPE_SK: + { + if (cart.special & HW_LOCK_ON) + { + /* disable UPMEM chip at $300000-$3fffff */ + for (i=0x30; i<0x40; i++) + { + m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); + } + } + break; + } + + default: + { + break; + } + } +} + +int md_cart_context_save(uint8 *state) +{ + int i; + int bufferptr = 0; + uint8 *base; + + /* cartridge mapping */ + for (i=0; i<0x40; i++) + { + /* get base address */ + base = m68k.memory_map[i].base; + + if (base == sram.sram) + { + /* SRAM */ + state[bufferptr++] = 0xff; + } + else + { + /* ROM */ + state[bufferptr++] = ((base - cart.rom) >> 16) & 0xff; + } + } + + /* hardware registers */ + save_param(cart.hw.regs, sizeof(cart.hw.regs)); + + /* SVP */ + if (svp) + { + save_param(svp->iram_rom, 0x800); + save_param(svp->dram,sizeof(svp->dram)); + save_param(&svp->ssp1601,sizeof(ssp1601_t)); + } + + return bufferptr; +} + +int md_cart_context_load(uint8 *state) +{ + int i; + int bufferptr = 0; + uint8 offset; + + /* cartridge mapping */ + for (i=0; i<0x40; i++) + { + /* get offset */ + offset = state[bufferptr++]; + + if (offset == 0xff) + { + /* SRAM */ + m68k.memory_map[i].base = sram.sram; + m68k.memory_map[i].read8 = sram_read_byte; + m68k.memory_map[i].read16 = sram_read_word; + m68k.memory_map[i].write8 = sram_write_byte; + m68k.memory_map[i].write16 = sram_write_word; + zbank_memory_map[i].read = sram_read_byte; + zbank_memory_map[i].write = sram_write_byte; + + } + else + { + /* check if SRAM was mapped there before loading state */ + if (m68k.memory_map[i].base == sram.sram) + { + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].read = NULL; + zbank_memory_map[i].write = zbank_unused_w; + } + + /* ROM */ + m68k.memory_map[i].base = cart.rom + (offset << 16); + } + } + + /* hardware registers */ + load_param(cart.hw.regs, sizeof(cart.hw.regs)); + + /* SVP */ + if (svp) + { + load_param(svp->iram_rom, 0x800); + load_param(svp->dram,sizeof(svp->dram)); + load_param(&svp->ssp1601,sizeof(ssp1601_t)); + } + + return bufferptr; +} + +/************************************************************ + MAPPER handlers +*************************************************************/ + +/* + "official" ROM/SRAM bankswitch (Phantasy Star IV, Story of Thor/Beyond Oasis, Sonic 3 & Knuckles) +*/ +static void mapper_sega_w(uint32 data) +{ + int i; + + if (data & 1) + { + if (sram.on) + { + /* Backup RAM mapped to $200000-$20ffff (normally mirrored up to $3fffff but this breaks Sonic Megamix and no game need it) */ + m68k.memory_map[0x20].base = sram.sram; + m68k.memory_map[0x20].read8 = sram_read_byte; + m68k.memory_map[0x20].read16 = sram_read_word; + zbank_memory_map[0x20].read = sram_read_byte; + + /* Backup RAM write protection */ + if (data & 2) + { + m68k.memory_map[0x20].write8 = m68k_unused_8_w; + m68k.memory_map[0x20].write16 = m68k_unused_16_w; + zbank_memory_map[0x20].write = zbank_unused_w; + } + else + { + m68k.memory_map[0x20].write8 = sram_write_byte; + m68k.memory_map[0x20].write16 = sram_write_word; + zbank_memory_map[0x20].write = sram_write_byte; + } + } + + /* S&K lock-on chip */ + if ((cart.special & HW_LOCK_ON) && (config.lock_on == TYPE_SK)) + { + /* S2K upmem chip mapped to $300000-$3fffff (256K mirrored) */ + for (i=0x30; i<0x40; i++) + { + m68k.memory_map[i].base = (cart.rom + 0x900000) + ((i & 3) << 16); + } + } + } + else + { + /* cartridge ROM mapped to $200000-$3fffff */ + for (i=0x20; i<0x40; i++) + { + m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].write = zbank_unused_w; + } + } +} + +/* + Super Street Fighter 2 ROM bankswitch + documented by Bart Trzynadlowski (http://www.trzy.org/files/ssf2.txt) +*/ +static void mapper_ssf2_w(uint32 address, uint32 data) +{ + /* 8 x 512k banks */ + address = (address << 2) & 0x38; + + /* bank 0 remains unchanged */ + if (address) + { + uint32 i; + uint8 *src = cart.rom + (data << 19); + + for (i=0; i<8; i++) + { + m68k.memory_map[address++].base = src + (i<<16); + } + } +} + +/* + SF-001 mapper +*/ +static void mapper_sf001_w(uint32 address, uint32 data) +{ + switch ((address >> 8) & 0xf) + { + case 0xe: + { + int i; + + /* bit 6: enable / disable cartridge access */ + if (data & 0x40) + { + /* $000000-$3FFFFF is not mapped */ + for (i=0x00; i<0x40; i++) + { + m68k.memory_map[i].base = cart.rom + (i << 16); + m68k.memory_map[i].read8 = m68k_read_bus_8; + m68k.memory_map[i].read16 = m68k_read_bus_16; + m68k.memory_map[i].write8 = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; + m68k.memory_map[i].write16 = (i > 0x00) ? m68k_unused_16_w : mapper_sf001_w; + zbank_memory_map[i].read = zbank_unused_r; + zbank_memory_map[i].write = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; + } + } + + /* bit 7: enable / disable SRAM & ROM bankswitching */ + else if (data & 0x80) + { + /* 256K ROM bank #15 mapped to $000000-$03FFFF */ + for (i=0x00; i<0x04; i++) + { + m68k.memory_map[i].base = cart.rom + ((0x38 + i) << 16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + } + + /* 256K ROM banks #2 to #15 mapped to $040000-$3BFFFF (last revision) or $040000-$3FFFFF (older revisions) */ + for (i=0x04; i<(sram.start >> 16); i++) + { + m68k.memory_map[i].base = cart.rom + (i << 16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + } + + /* 32K static RAM mirrored into $3C0000-$3FFFFF (odd bytes only) (last revision only) */ + while (i<0x40) + { + m68k.memory_map[i].base = sram.sram; + m68k.memory_map[i].read8 = sram_read_byte; + m68k.memory_map[i].read16 = sram_read_word; + m68k.memory_map[i].write8 = sram_write_byte; + m68k.memory_map[i].write16 = sram_write_word; + zbank_memory_map[i].read = sram_read_byte; + zbank_memory_map[i].write = sram_write_byte; + i++; + } + } + else + { + /* 256K ROM banks #1 to #16 mapped to $000000-$3FFFFF (default) */ + for (i=0x00; i<0x40; i++) + { + m68k.memory_map[i].base = cart.rom + (i << 16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + m68k.memory_map[i].write8 = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; + m68k.memory_map[i].write16 = (i > 0x00) ? m68k_unused_16_w : mapper_sf001_w; + zbank_memory_map[i].read = NULL; + zbank_memory_map[i].write = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; + } + } + + /* bit 5: lock bankswitch hardware when set */ + if (data & 0x20) + { + /* disable bankswitch hardware access until hard reset */ + m68k.memory_map[0x00].write8 = m68k_unused_8_w; + m68k.memory_map[0x00].write16 = m68k_unused_16_w; + zbank_memory_map[0x00].write = m68k_unused_8_w; + } + + return; + } + + default: + { + m68k_unused_8_w(address, data); + return; + } + } +} + +/* + SF-002 mapper +*/ +static void mapper_sf002_w(uint32 address, uint32 data) +{ + int i; + if (data & 0x80) + { + /* $000000-$1BFFFF mapped to $200000-$3BFFFF */ + for (i=0x20; i<0x3C; i++) + { + m68k.memory_map[i].base = cart.rom + ((i & 0x1F) << 16); + } + } + else + { + /* $200000-$3BFFFF mapped to $200000-$3BFFFF */ + for (i=0x20; i<0x3C; i++) + { + m68k.memory_map[i].base = cart.rom + (i << 16); + } + } +} + +/* + SF-004 mapper +*/ +static void mapper_sf004_w(uint32 address, uint32 data) +{ + int i; + switch ((address >> 8) & 0xf) + { + case 0xd: + { + /* bit 7: enable/disable static RAM access */ + if (data & 0x80) + { + /* 32KB static RAM mirrored into $200000-$2FFFFF (odd bytes only) */ + for (i=0x20; i<0x30; i++) + { + m68k.memory_map[i].read8 = sram_read_byte; + m68k.memory_map[i].read16 = sram_read_word; + m68k.memory_map[i].write8 = sram_write_byte; + m68k.memory_map[i].write16 = sram_write_word; + zbank_memory_map[i].read = sram_read_byte; + zbank_memory_map[i].write = sram_write_byte; + } + } + else + { + /* 32KB static RAM disabled at $200000-$2FFFFF */ + for (i=0x20; i<0x30; i++) + { + m68k.memory_map[i].read8 = m68k_read_bus_8; + m68k.memory_map[i].read16 = m68k_read_bus_16; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].read = m68k_read_bus_8; + zbank_memory_map[i].write = m68k_unused_8_w; + } + } + + return; + } + + case 0x0e: + { + /* bit 5: enable / disable cartridge ROM access */ + if (data & 0x20) + { + /* $000000-$1FFFFF is not mapped */ + for (i=0x00; i<0x20; i++) + { + m68k.memory_map[i].read8 = m68k_read_bus_8; + m68k.memory_map[i].read16 = m68k_read_bus_16; + zbank_memory_map[i].read = m68k_read_bus_8; + } + } + + /* bit 6: enable / disable first page mirroring */ + else if (data & 0x40) + { + /* first page ROM bank */ + uint8 base = (m68k.memory_map[0x00].base - cart.rom) >> 16; + + /* 5 x 256K ROM banks mapped to $000000-$13FFFF, starting from first page ROM bank */ + for (i=0x00; i<0x14; i++) + { + m68k.memory_map[i].base = cart.rom + (((base + i) & 0x1f) << 16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + } + + /* $140000-$1FFFFF is not mapped */ + for (i=0x14; i<0x20; i++) + { + m68k.memory_map[i].read8 = m68k_read_bus_8; + m68k.memory_map[i].read16 = m68k_read_bus_16; + zbank_memory_map[i].read = m68k_read_bus_8; + } + } + else + { + /* first page 256K ROM bank mirrored into $000000-$1FFFFF */ + for (i=0x00; i<0x20; i++) + { + m68k.memory_map[i].base = m68k.memory_map[0].base + ((i & 0x03) << 16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + } + } + + /* bit 7: lock ROM bankswitching hardware when cleared */ + if (!(data & 0x80)) + { + /* disable bankswitch hardware access */ + m68k.memory_map[0x00].write8 = m68k_unused_8_w; + m68k.memory_map[0x00].write16 = m68k_unused_16_w; + zbank_memory_map[0x00].write = m68k_unused_8_w; + } + + return; + } + + case 0x0f: + { + /* bits 6-4: select first page ROM bank (8 x 256K ROM banks) */ + uint8 base = ((data >> 4) & 7) << 2; + + if (m68k.memory_map[0].base == m68k.memory_map[4].base) + { + /* selected 256K ROM bank mirrored into $000000-$1FFFFF */ + for (i=0x00; i<0x20; i++) + { + m68k.memory_map[i].base = cart.rom + ((base + (i & 0x03)) << 16); + } + } + else + { + /* 5 x 256K ROM banks mapped to $000000-$13FFFF, starting from selected bank */ + for (i=0x00; i<0x14; i++) + { + m68k.memory_map[i].base = cart.rom + (((base + i) & 0x1f) << 16); + } + } + + return; + } + + default: + { + m68k_unused_8_w(address, data); + return; + } + } +} + +static uint32 mapper_sf004_r(uint32 address) +{ + /* return first page 256K bank index ($00,$10,$20,...,$70) */ + return (((m68k.memory_map[0x00].base - cart.rom) >> 18) << 4); +} + +/* + T-5740xx-xx mapper +*/ +static void mapper_t5740_w(uint32 address, uint32 data) +{ + int i; + uint8 *base; + + switch (address & 0xff) + { + case 0x01: /* mode register */ + { + /* bits 7-4: unused ? */ + /* bit 3: enable SPI registers access ? */ + /* bit 2: not used ? */ + /* bit 1: enable bankswitch registers access ? */ + /* bit 0: always set, enable hardware access ? */ + return; + } + + case 0x03: /* page #5 register */ + { + /* map any of 16 x 512K ROM banks to $280000-$2FFFFF */ + base = cart.rom + ((data & 0x0f) << 19); + for (i=0x28; i<0x30; i++) + { + m68k.memory_map[i].base = base + ((i & 0x07) << 16); + } + return; + } + + case 0x05: /* page #6 register */ + { + /* map any of 16 x 512K ROM banks to $300000-$37FFFF */ + base = cart.rom + ((data & 0x0f) << 19); + for (i=0x30; i<0x38; i++) + { + m68k.memory_map[i].base = base + ((i & 0x07) << 16); + } + return; + } + + case 0x07: /* page #7 register */ + { + /* map any of 16 x 512K ROM banks to $380000-$3FFFFF */ + base = cart.rom + ((data & 0x0f) << 19); + for (i=0x38; i<0x40; i++) + { + m68k.memory_map[i].base = base + ((i & 0x07) << 16); + } + return; + } + + case 0x09: /* serial EEPROM SPI board support */ + { + eeprom_spi_write(data); + return; + } + + default: + { + /* unknown registers */ + m68k_unused_8_w(address, data); + return; + } + } +} + +static uint32 mapper_t5740_r(uint32 address) +{ + /* By default, first 32K of each eight 512K pages mapped in $000000-$3FFFFF are mirrored in the 512K page */ + /* mirroring is disabled/enabled when a specific number of words is being read from specific ROM addresses */ + /* Exact decoding isn't known but mirrored data is expected on startup when reading a few times from $181xx */ + /* this area doesn't seem to be accessed as byte later so it seems safe to always return mirrored data here */ + if ((address & 0xff00) == 0x8100) + { + return READ_BYTE(cart.rom , (address & 0x7fff)); + } + + return READ_BYTE(cart.rom, address); +} + +/* + Super Mario World 64 (unlicensed) mapper +*/ +static void mapper_smw_64_w(uint32 address, uint32 data) +{ + /* internal registers (saved to backup RAM) */ + switch ((address >> 16) & 0x07) + { + case 0x00: /* $60xxxx */ + { + if (address & 2) + { + /* $600003 data write mode ? */ + switch (sram.sram[0x00] & 0x07) + { + case 0x00: + { + /* update value returned at $660001-$660003 */ + sram.sram[0x06] = ((sram.sram[0x06] ^ sram.sram[0x01]) ^ data) & 0xFE; + break; + } + + case 0x01: + { + /* update value returned at $660005-$660007 */ + sram.sram[0x07] = data & 0xFE; + break; + } + + case 0x07: + { + /* update selected ROM bank (upper 512K) mapped at $610000-$61ffff */ + m68k.memory_map[0x61].base = m68k.memory_map[0x69].base = cart.rom + 0x080000 + ((data & 0x1c) << 14); + break; + } + + default: + { + /* unknown mode */ + break; + } + } + + /* $600003 data register */ + sram.sram[0x01] = data; + } + else + { + /* $600001 ctrl register */ + sram.sram[0x00] = data; + } + return; + } + + case 0x01: /* $61xxxx */ + { + if (address & 2) + { + /* $610003 ctrl register */ + sram.sram[0x02] = data; + } + return; + } + + case 0x04: /* $64xxxx */ + { + if (address & 2) + { + /* $640003 data register */ + sram.sram[0x04] = data; + } + else + { + /* $640001 data register */ + sram.sram[0x03] = data; + } + return; + } + + case 0x06: /* $66xxxx */ + { + /* unknown */ + return; + } + + case 0x07: /* $67xxxx */ + { + if (!(address & 2)) + { + /* $670001 ctrl register */ + sram.sram[0x05] = data; + + /* upper 512K ROM bank-switching enabled ? */ + if (sram.sram[0x02] & 0x80) + { + /* update selected ROM bank (upper 512K) mapped at $600000-$60ffff */ + m68k.memory_map[0x60].base = m68k.memory_map[0x68].base = cart.rom + 0x080000 + ((data & 0x1c) << 14); + } + } + return; + } + + default: /* not used */ + { + m68k_unused_8_w(address, data); + return; + } + } +} + +static uint32 mapper_smw_64_r(uint32 address) +{ + /* internal registers (saved to backup RAM) */ + switch ((address >> 16) & 0x03) + { + case 0x02: /* $66xxxx */ + { + switch ((address >> 1) & 7) + { + case 0x00: return sram.sram[0x06]; + case 0x01: return sram.sram[0x06] + 1; + case 0x02: return sram.sram[0x07]; + case 0x03: return sram.sram[0x07] + 1; + case 0x04: return sram.sram[0x08]; + case 0x05: return sram.sram[0x08] + 1; + case 0x06: return sram.sram[0x08] + 2; + case 0x07: return sram.sram[0x08] + 3; + } + } + + case 0x03: /* $67xxxx */ + { + uint8 data = (sram.sram[0x02] & 0x80) ? ((sram.sram[0x05] & 0x40) ? (sram.sram[0x03] & sram.sram[0x04]) : (sram.sram[0x03] ^ 0xFF)) : 0x00; + + if (address & 2) + { + /* $670003 */ + data &= 0x7f; + } + else + { + /* $66xxxx data registers update */ + if (sram.sram[0x05] & 0x80) + { + if (sram.sram[0x05] & 0x20) + { + /* update $660009-$66000f data register */ + sram.sram[0x08] = (sram.sram[0x04] << 2) & 0xFC; + } + else + { + /* update $660001-$660003 data register */ + sram.sram[0x06] = (sram.sram[0x01] ^ (sram.sram[0x03] << 1)) & 0xFE; + } + } + } + + return data; + } + + default: /* 64xxxx-$65xxxx */ + { + return 0x00; + } + } +} + +/* + Realtec ROM bankswitch (Earth Defend, Balloon Boy & Funny World, Whac-A-Critter) + (Note: register usage is inverted in TascoDlx documentation) +*/ +static void mapper_realtec_w(uint32 address, uint32 data) +{ + switch (address) + { + case 0x402000: + { + /* number of mapped 64k blocks (the written value is a number of 128k blocks) */ + cart.hw.regs[2] = data << 1; + return; + } + + case 0x404000: + { + /* 00000xxx */ + cart.hw.regs[0] = data & 7; + return; + } + + case 0x400000: + { + /* 00000yy1 */ + cart.hw.regs[1] = data & 6; + + /* ensure mapped size is not null */ + if (cart.hw.regs[2]) + { + /* mapped start address is 00yy xxx0 0000 0000 0000 0000 */ + uint32 base = (cart.hw.regs[0] << 1) | (cart.hw.regs[1] << 3); + + /* selected blocks are mirrored into the whole cartridge area */ + int i; + for (i=0x00; i<0x40; i++) + { + m68k.memory_map[i].base = &cart.rom[(base + (i % cart.hw.regs[2])) << 16]; + } + } + return; + } + } +} + +/* Game no Kanzume Otokuyou ROM Mapper */ +static void mapper_seganet_w(uint32 address, uint32 data) +{ + if ((address & 0xff) == 0xf1) + { + int i; + if (data & 1) + { + /* ROM Write protected */ + for (i=0; i<0x40; i++) + { + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].write = zbank_unused_w; + } + } + else + { + /* ROM Write enabled */ + for (i=0; i<0x40; i++) + { + m68k.memory_map[i].write8 = NULL; + m68k.memory_map[i].write16 = NULL; + zbank_memory_map[i].write = NULL; + } + } + } +} + +/* + Custom ROM Bankswitch used in Soul Edge VS Samurai Spirits, Top Fighter, Mulan, Pocket Monsters II, Lion King 3, Super King Kong 99, Pokemon Stadium +*/ +static void mapper_32k_w(uint32 data) +{ + int i; + + /* 64 x 32k banks */ + if (data) + { + for (i=0; i<0x10; i++) + { + /* Remap to unused ROM area */ + m68k.memory_map[i].base = &cart.rom[0x400000 + (i << 16)]; + + /* address = address OR (value << 15) */ + memcpy(m68k.memory_map[i].base, cart.rom + ((i << 16) | (data & 0x3f) << 15), 0x8000); + memcpy(m68k.memory_map[i].base + 0x8000, cart.rom + ((i << 16) | ((data | 1) & 0x3f) << 15), 0x8000); + } + } + else + { + /* reset default $000000-$0FFFFF mapping */ + for (i=0; i<16; i++) + { + m68k.memory_map[i].base = &cart.rom[i << 16]; + } + } +} + +/* + Custom ROM Bankswitch used in Chinese Fighter III +*/ +static void mapper_64k_w(uint32 data) +{ + int i; + + /* 16 x 64k banks */ + if (data) + { + /* bank is mapped at $000000-$0FFFFF */ + for (i=0; i<16; i++) + { + m68k.memory_map[i].base = &cart.rom[(data & 0xf) << 16]; + } + } + else + { + /* reset default $000000-$0FFFFF mapping */ + for (i=0; i<16; i++) + { + m68k.memory_map[i].base = &cart.rom[(i & 0xf) << 16]; + } + } +} + +/* + Custom ROM Bankswitch used in pirate "Multi-in-1" cartridges, A Bug's Life, King of Fighter 99, Pocket Monster, Rockman X3 + */ +static void mapper_64k_multi_w(uint32 address) +{ + int i; + + /* 64 x 64k banks */ + for (i=0; i<64; i++) + { + m68k.memory_map[i].base = &cart.rom[((address++) & 0x3f) << 16]; + } +} + +/* + Custom ROM Bankswitch used in RADICA cartridges +*/ +static uint32 mapper_radica_r(uint32 address) +{ + int i = 0; + address = (address >> 1); + + /* 64 x 64k banks */ + for (i = 0; i < 64; i++) + { + m68k.memory_map[i].base = &cart.rom[((address++)& 0x3f)<< 16]; + } + + return 0xffff; +} + + +/************************************************************ + default !TIME signal handler +*************************************************************/ + +static void default_time_w(uint32 address, uint32 data) +{ + if (address < 0xa13040) + { + /* unlicensed cartridges mapper (default) */ + mapper_64k_multi_w(address); + return; + } + + /* official cartridges mapper (default) */ + mapper_sega_w(data); +} + + +/************************************************************ + Internal register handlers +*************************************************************/ + +static uint32 default_regs_r(uint32 address) +{ + int i; + for (i=0; i<4; i++) + { + if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) + { + return cart.hw.regs[i]; + } + } + return m68k_read_bus_8(address); +} + +static uint32 default_regs_r_16(uint32 address) +{ + int i; + for (i=0; i<4; i++) + { + if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) + { + return (cart.hw.regs[i] << 8); + } + } + return m68k_read_bus_16(address); +} + +static void default_regs_w(uint32 address, uint32 data) +{ + int i; + for (i=0; i<4; i++) + { + if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) + { + cart.hw.regs[i] = data; + return; + } + } + m68k_unused_8_w(address, data); +} + +/* basic register shifting hardware (Bug's Life, Pocket Monster) */ +static uint32 custom_regs_r(uint32 address) +{ + int i; + for (i=0; i<4; i++) + { + if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) + { + return cart.hw.regs[i] >> 1; + } + } + + return m68k_read_bus_8(address); +} + +/* custom register hardware (Top Fighter, Lion King III, Super Donkey Kong 99, Mulan, Pocket Monsters II, Pokemon Stadium) */ +static void custom_regs_w(uint32 address, uint32 data) +{ + uint8 temp; + + /* ROM bankswitch */ + if ((address >> 16) > 0x6f) + { + mapper_32k_w(data); + return; + } + + /* write register */ + default_regs_w(address, data); + + /* bitswapping */ + temp = cart.hw.regs[0]; + switch (cart.hw.regs[1] & 3) + { + case 0: + cart.hw.regs[2] = (temp << 1); + break; + + case 1: + cart.hw.regs[2] = (temp >> 1); + return; + + case 2: + cart.hw.regs[2] = ((temp >> 4) | ((temp & 0x0F) << 4)); + return; + + default: + cart.hw.regs[2] = (((temp >> 7) & 0x01) | ((temp >> 5) & 0x02) | + ((temp >> 3) & 0x04) | ((temp >> 1) & 0x08) | + ((temp << 1) & 0x10) | ((temp << 3) & 0x20) | + ((temp << 5) & 0x40) | ((temp << 7) & 0x80)); + return; + } +} + +/* alternate custom register hardware (Chinese Fighters III) */ +static void custom_alt_regs_w(uint32 address, uint32 data) +{ + /* ROM bankswitch */ + if ((address >> 16) > 0x5f) + { + mapper_64k_w(data); + return; + } + + /* write regs */ + default_regs_w(address, data); +} + + +/* "Tekken 3 Special" custom register hardware */ +static uint32 tekken_regs_r(uint32 address) +{ + /* data output */ + if ((address & 0x0e) == 0x02) + { + /* maybe depends on mode bits ? */ + return (cart.hw.regs[0] - 1); + } + + return m68k_read_bus_16(address); +} + +static void tekken_regs_w(uint32 address, uint32 data) +{ + switch (address & 0x0e) + { + case 0x00: + { + /* data output reset ? (game writes $FF before & after protection check) */ + cart.hw.regs[0]= 0x00; + break; + } + + case 0x02: + { + /* read only ? */ + break; + } + + case 0x0c: + { + /* data output mode bit 0 ? (game writes $01) */ + break; + } + + case 0x0e: + { + /* data output mode bit 1 ? (never written by game) */ + break; + } + + default: + { + /* data input (only connected to D0 ?)*/ + if (data & 1) + { + /* 4-bit hardware register ($400004 corresponds to bit0, $400006 to bit1, etc) */ + cart.hw.regs[0] |= 1 << (((address - 0x04) >> 1) & 3); + } + break; + } + } +} + +/* "Top Shooter" arcade board hardware */ +static uint32 topshooter_r(uint32 address) +{ + if (address < 0x202000) + { + uint8 temp = 0xff; + + switch (address & 0xff) + { + case 0x43: + { + if (input.pad[0] & INPUT_A) temp &= ~0x80; /* Shoot */ + if (input.pad[0] & INPUT_B) temp &= ~0x10; /* Bet */ + if (input.pad[0] & INPUT_START) temp &= ~0x20; /* Start */ + break; + } + + case 0x45: /* ??? (DOWN) & Service Mode (UP) */ + { + if (input.pad[0] & INPUT_UP) temp &= ~0x08; /* Service Mode */ + if (input.pad[0] & INPUT_DOWN) temp &= ~0x10; /* ???, used in service menu to select next option */ + break; + } + + case 0x47: + { + if (input.pad[0] & INPUT_RIGHT) temp &= ~0x03; /* Insert 10 coins */ + break; + } + + case 0x49: + { + if (input.pad[0] & INPUT_LEFT) temp &= ~0x03; /* Clear coins */ + if (input.pad[0] & INPUT_C) temp &= ~0x01; /* Insert XXX coins */ + break; + } + + case 0x51: + { + temp = 0xA5; + break; + } + + default: + { + temp = m68k_read_bus_8(address); + break; + } + } + return temp; + } + + return READ_BYTE(sram.sram , address & 0xffff); +} + +static void topshooter_w(uint32 address, uint32 data) +{ + if (address >= 0x202000) + { + WRITE_BYTE(sram.sram , address & 0xffff, data); + return; + } + + m68k_unused_8_w(address, data); +} + + +/* Sega Channel hardware (not emulated) */ +/* + +$A13004: BUSY ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? + +Unused read16 00A13004 (00005B54) +Unused read16 00A13004 (00005B70) +Unused read16 00A13006 (00005B7C) + +Unused read16 00A13004 (00005BC4) +Unused read16 00A13004 (00005BDA) + +Unused write16 00A13032 = 0004 (00005706) +Unused write16 00A130F0 = 0000 (0000570E) + +Unused write16 00A130F0 = 0000 (0000463E) +Unused write16 00A130F2 = 0001 (00004646) +Unused write16 00A130F4 = 0002 (0000464E) +Unused write16 00A130F6 = 0003 (00004656) +Unused write16 00A130F8 = 0004 (0000465E) +Unused write16 00A130FA = 0005 (00004666) + +Unused write16 00A13032 = 0004 (00005706) +Unused write16 00A13032 = 0104 (0000579E) + +Unused write16 00380000 = ACDC (00005718) +Unused write16 00380002 = 0000 (00005722) +Unused read16 00380000 (0000572C) +Unused write16 00A13032 = 0104 (0000579E) +Unused write16 00300000 = ACDC (000057B2) +Unused write16 00380000 = 0000 (000057BC) +Unused read16 00300000 (000057C6) + +static uint32 sega_channel_r(uint32 address) +{ + return m68k_read_bus_16(address);; +} + +static void sega_channel_w(uint32 address, uint32 data) +{ + m68k_unused_16_w(address, data); +} +*/ diff --git a/genplus-gx/core/cart_hw/md_cart.h b/genplus-gx/core/cart_hw/md_cart.h new file mode 100644 index 0000000000..24c0bee038 --- /dev/null +++ b/genplus-gx/core/cart_hw/md_cart.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * Genesis Plus + * Mega Drive cartridge hardware support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Most cartridge protections were initially documented by Haze + * (http://haze.mameworld.info/) + * + * Realtec mapper was documented by TascoDeluxe + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _MD_CART_H_ +#define _MD_CART_H_ + +#define cart ext.md_cart + +/* Lock-On cartridge type */ +#define TYPE_GG 0x01 /* Game Genie */ +#define TYPE_AR 0x02 /* (Pro) Action Replay */ +#define TYPE_SK 0x03 /* Sonic & Knuckles */ + +/* Special hardware (0x01 & 0x02 reserved for Master System 3-D glasses & Terebi Oekaki) */ +#define HW_J_CART 0x04 +#define HW_LOCK_ON 0x08 + +/* Cartridge extra hardware */ +typedef struct +{ + uint8 regs[4]; /* internal registers (R/W) */ + uint32 mask[4]; /* registers address mask */ + uint32 addr[4]; /* registers address */ + uint16 realtec; /* realtec mapper */ + uint16 bankshift; /* cartridge with bankshift mecanism reseted on software reset */ + unsigned int (*time_r)(unsigned int address); /* !TIME signal ($a130xx) read handler */ + void (*time_w)(unsigned int address, unsigned int data); /* !TIME signal ($a130xx) write handler */ + unsigned int (*regs_r)(unsigned int address); /* cart hardware registers read handler */ + void (*regs_w)(unsigned int address, unsigned int data); /* cart hardware registers write handler */ +} cart_hw_t; + +/* Cartridge type */ +typedef struct +{ + uint8 rom[MAXROMSIZE]; /* ROM area */ + uint8 *base; /* ROM base (saved for OS/Cartridge ROM swap) */ + uint32 romsize; /* ROM size */ + uint32 mask; /* ROM mask */ + uint8 special; /* Lock-On, J-Cart or SMS 3-D glasses hardware */ + cart_hw_t hw; /* Extra mapping hardware */ +} md_cart_t; + + +/* Function prototypes */ +extern void md_cart_init(void); +extern void md_cart_reset(int hard_reset); +extern int md_cart_context_save(uint8 *state); +extern int md_cart_context_load(uint8 *state); + +#endif diff --git a/genplus-gx/core/cart_hw/sms_cart.c b/genplus-gx/core/cart_hw/sms_cart.c new file mode 100644 index 0000000000..1d3728e1c4 --- /dev/null +++ b/genplus-gx/core/cart_hw/sms_cart.c @@ -0,0 +1,1324 @@ +/**************************************************************************** + * Genesis Plus + * SG-1000, Master System & Game Gear cartridge hardware support + * + * Copyright (C) 2007-2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "eeprom_93c.h" +#include "terebi_oekaki.h" + +#define MAPPER_NONE (0x00) +#define MAPPER_TEREBI (0x01) +#define MAPPER_RAM_8K_EXT1 (0x02) +#define MAPPER_RAM_8K_EXT2 (0x03) +#define MAPPER_SEGA (0x10) +#define MAPPER_SEGA_X (0x11) +#define MAPPER_93C46 (0x12) +#define MAPPER_CODIES (0x13) +#define MAPPER_MULTI (0x14) +#define MAPPER_KOREA (0x15) +#define MAPPER_KOREA_16K (0x16) +#define MAPPER_KOREA_8K (0x20) +#define MAPPER_MSX (0x21) +#define MAPPER_MSX_NEMESIS (0x22) + +#define GAME_DATABASE_CNT (211) + +typedef struct +{ + uint32 crc; + uint8 g_3d; + uint8 fm; + uint8 peripheral; + uint8 mapper; + uint8 system; + uint8 region; +} rominfo_t; + +typedef struct +{ + uint8 fcr[4]; + uint8 mapper; + uint8 pages; +} romhw_t; + +static const rominfo_t game_list[GAME_DATABASE_CNT] = +{ + /* program requiring Mega Drive VDP (Mode 5) */ + {0x47FA618D, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_PBC, REGION_USA}, /* Charles MacDonald's Mode 5 Demo Program */ + + /* game requiring SEGA mapper */ + {0xFF67359B, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* DataStorm (homebrew) */ + + /* games requiring 315-5124 VDP (Mark-III, Master System I) */ + {0x32759751, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Y's (J) */ + + /* games requiring Sega 315-5235 mapper without bank shifting */ + {0x23BAC434, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA_X, SYSTEM_GG, REGION_USA}, /* Shining Force Gaiden - Final Conflict (JP) [T-Eng] */ + + /* games using various Korean mappers */ + {0x17AB6883, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_NONE, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* FA Tetris (KR) */ + {0x61E8806F, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_NONE, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Flash Point (KR) */ + {0x445525E2, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Penguin Adventure (KR) */ + {0x83F0EEDE, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Street Master (KR) */ + {0xA05258F5, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Won-Si-In (KR) */ + {0x06965ED9, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* F-1 Spirit - The way to Formula-1 (KR) */ + {0x77EFE84A, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Cyborg Z (KR) */ + {0xF89AF3CC, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Knightmare II - The Maze of Galious (KR) */ + {0x9195C34C, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Super Boy 3 (KR) */ + {0xE316C06D, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX_NEMESIS, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Nemesis (KR) */ + {0x0A77FA5E, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MSX, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Nemesis 2 (KR) */ + {0xA67F2A5C, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_MULTI, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* 4-Pak All Action (KR) */ + {0x89B79E77, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Dodgeball King (KR) */ + {0x18FB98A3, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Jang Pung 3 (KR) */ + {0x97D03541, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Sangokushi 3 (KR) */ + {0x67C2F0FF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Super Boy 2 (KR) */ + {0x192949D5, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA_8K, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Janggun-ui Adeul (KR) */ + {0x9FA727A0, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA_16K, SYSTEM_GGMS, REGION_USA}, /* Street Hero [Proto 0] [SMS-GG] (US) */ + {0xFB481971, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_KOREA_16K, SYSTEM_GGMS, REGION_USA}, /* Street Hero [Proto 1] [SMS-GG] (US) */ + + /* games using Codemaster mapper */ + {0x29822980, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_SMS2, REGION_EUROPE}, /* Cosmic Spacehead */ + {0x8813514B, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_SMS2, REGION_EUROPE}, /* Excellent Dizzy Collection, The [Proto] */ + {0xB9664AE1, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_SMS2, REGION_EUROPE}, /* Fantastic Dizzy */ + {0xA577CE46, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_SMS2, REGION_EUROPE}, /* Micro Machines */ + {0xEA5C3A6F, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_SMS2, REGION_USA}, /* Dinobasher - Starring Bignose the Caveman [Proto] */ + {0xAA140C9C, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_GGMS, REGION_USA}, /* Excellent Dizzy Collection, The [SMS-GG] */ + {0xC888222B, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_GGMS, REGION_USA}, /* Fantastic Dizzy [SMS-GG] */ + {0x76C5BDFB, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_GGMS, REGION_USA}, /* Jang Pung 2 [SMS-GG] */ + {0x6CAA625B, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_GG, REGION_USA}, /* Cosmic Spacehead [GG]*/ + {0x152F0DCC, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_GG, REGION_USA}, /* Drop Zone" */ + {0x5E53C7F7, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_GG, REGION_USA}, /* Ernie Els Golf */ + {0xD9A7F170, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_GG, REGION_USA}, /* Man Overboard! */ + {0xF7C524F6, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_GG, REGION_USA}, /* Micro Machines [GG] */ + {0xDBE8895C, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_GG, REGION_USA}, /* Micro Machines 2 - Turbo Tournament */ + {0xC1756BEE, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_GG, REGION_USA}, /* Pete Sampras Tennis */ + {0x72981057, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_CODIES, SYSTEM_GG, REGION_USA}, /* CJ Elephant Fugitive */ + + /* games using serial EEPROM */ + {0x36EBCD6D, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_93C46, SYSTEM_GG, REGION_USA}, /* Majors Pro Baseball */ + {0x3D8D0DD6, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_93C46, SYSTEM_GG, REGION_USA}, /* World Series Baseball [v0] */ + {0xBB38CFD7, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_93C46, SYSTEM_GG, REGION_USA}, /* World Series Baseball [v1] */ + {0x578A8A38, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_93C46, SYSTEM_GG, REGION_USA}, /* World Series Baseball '95 */ + + /* games using Terebi Oekaki graphic board */ + {0xDD4A661B, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_TEREBI, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Terebi Oekaki */ + + /* games requiring 8K RAM extension adapter */ + {0xCE5648C3, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT1, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Bomberman Special [DahJee] (TW) */ + {0x223397A1, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT1, SYSTEM_SG, REGION_JAPAN_NTSC}, /* King's Valley (TW) */ + {0x281D2888, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT1, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Knightmare (TW) */ + {0x306D5F78, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT1, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Rally-X [DahJee] (TW) */ + {0x29E047CC, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT1, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Road Fighter (TW) */ + {0x5CBD1163, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT1, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Tank Battalion (TW) */ + {0x2E7166D5, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT1, SYSTEM_SG, REGION_JAPAN_NTSC}, /* The Legend of Kage (TW) */ + {0xC550B4F0, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT1, SYSTEM_SG, REGION_JAPAN_NTSC}, /* TwinBee (TW) */ + {0xFC87463C, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT1, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Yie Ar Kung-Fu II (TW) */ + {0x69FC1494, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT2, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Bomberman Special (TW) */ + {0xFFC4EE3F, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT2, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Magical Kid Wiz (TW) */ + {0x2E366CCF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT2, SYSTEM_SG, REGION_JAPAN_NTSC}, /* The Castle (TW) */ + {0xAAAC12CF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT2, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Rally-X (TW) */ + {0xD2EDD329, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_RAM_8K_EXT2, SYSTEM_SG, REGION_JAPAN_NTSC}, /* Road Fighter (TW) */ + + /* games requiring Japanese region setting */ + {0x71DEBA5A, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GG, REGION_JAPAN_NTSC}, /* Pop Breaker */ + {0xC9DD4E5F, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Woody Pop (Super Arkanoid) */ + + /* games requiring Mark-III hardware (no Memory Control port) */ + {0xBD1CC7DF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_MARKIII, REGION_JAPAN_NTSC}, /* Super Tetris (KR) */ + {0x6D309AC5, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_MARKIII, REGION_JAPAN_NTSC}, /* Power Boggle Boggle (KR) */ + + /* games requiring random RAM pattern initialization */ + {0x08BF3DE3, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_NONE, SYSTEM_MARKIII, REGION_JAPAN_NTSC}, /* Alibaba and 40 Thieves (KR) */ + {0x643B6B76, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_NONE, SYSTEM_MARKIII, REGION_JAPAN_NTSC}, /* Block Hole (KR) */ + + /* games requiring PAL timings */ + {0x72420F38, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Addams Familly */ + {0x2D48C1D3, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Back to the Future Part III */ + {0x1CBB7BF1, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Battlemaniacs (BR) */ + {0x1B10A951, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Bram Stoker's Dracula */ + {0xC0E25D62, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* California Games II */ + {0x45C50294, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Jogos de Verao II (BR) */ + {0xC9DBF936, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Home Alone */ + {0x0047B615, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Predator2 */ + {0xF42E145C, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Quest for the Shaven Yak Starring Ren Hoek & Stimpy (BR) */ + {0x9F951756, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* RoboCop 3 */ + {0xF8176918, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Sensible Soccer */ + {0x1575581D, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Shadow of the Beast */ + {0x96B3F29E, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Sonic Blast (BR) */ + {0x5B3B922C, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Sonic the Hedgehog 2 [V0] */ + {0xD6F2BFCA, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Sonic the Hedgehog 2 [V1] */ + {0xCA1D3752, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Space Harrier [50 Hz] */ + {0x85CFC9C9, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* Taito Chase H.Q. */ + {0x332A847D, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_EUROPE}, /* NBA Jam [Proto] */ + + /* games running in Game Gear MS compatibility mode */ + {0x59840FD6, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Castle of Illusion - Starring Mickey Mouse [SMS-GG] */ + {0x9C76FB3A, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Rastan Saga [SMS-GG] */ + {0xC8381DEF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Taito Chase H.Q [SMS-GG] */ + {0xDA8E95A9, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* WWF Wrestlemania Steel Cage Challenge [SMS-GG] */ + {0x1D93246E, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Olympic Gold [A][SMS-GG] */ + {0xA2F9C7AF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Olympic Gold [B][SMS-GG] */ + {0x01EAB89D, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Out Run Europa [SMS-GG] */ + {0xF037EC00, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Out Run Europa (US) [SMS-GG] */ + {0xE5F789B9, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Predator 2 [SMS-GG] */ + {0x311D2863, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Prince of Persia [A][SMS-GG] */ + {0x45F058D6, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Prince of Persia [B][SMS-GG] */ + {0x56201996, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* R.C. Grand Prix [SMS-GG] */ + {0x10DBBEF4, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_USA}, /* Super Kick Off [SMS-GG] */ + {0x9942B69B, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_JAPAN_NTSC}, /* Castle of Illusion - Starring Mickey Mouse (J) [SMS-GG] */ + {0x7BB81E3D, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_JAPAN_NTSC}, /* Taito Chase H.Q (J) [SMS-GG] */ + {0x6F8E46CF, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_JAPAN_NTSC}, /* Alex Kidd in Miracle World (TW) [SMS-GG] */ + {0x3382D73F, 0, 0, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_GGMS, REGION_JAPAN_NTSC}, /* Olympic Gold (TW) [SMS-GG] */ + + /* games requiring 3-D Glasses */ + {0x6BD5C2BF, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Space Harrier 3-D */ + {0x8ECD201C, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Blade Eagle 3-D */ + {0xFBF96C81, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Blade Eagle 3-D (BR) */ + {0x58D5FC48, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Blade Eagle 3-D [Proto] */ + {0x31B8040B, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Maze Hunter 3-D */ + {0xABD48AD2, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Poseidon Wars 3-D */ + {0xA3EF13CB, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Zaxxon 3-D */ + {0xBBA74147, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Zaxxon 3-D [Proto] */ + {0xD6F43DDA, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Out Run 3-D */ + {0x871562b0, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Maze Walker */ + {0x156948f9, 1, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Space Harrier 3-D (J) */ + + /* games requiring 3-D Glasses & Sega Light Phaser */ + {0xFBE5CFBB, 1, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Missile Defense 3D */ + {0xE79BB689, 1, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Missile Defense 3D [BIOS] */ + + /* games requiring Sega Light Phaser */ + {0x861B6E79, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Assault City [Light Phaser] */ + {0x5FC74D2A, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Gangster Town */ + {0xE167A561, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Hang-On / Safari Hunt */ + {0x91E93385, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Hang-On / Safari Hunt [BIOS] */ + {0xE8EA842C, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Marksman Shooting / Trap Shooting */ + {0xE8215C2E, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Marksman Shooting / Trap Shooting / Safari Hunt */ + {0x205CAAE8, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Operation Wolf */ + {0x23283F37, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Operation Wolf [A] */ + {0xDA5A7013, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Rambo 3 */ + {0x79AC8E7F, 0, 1, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Rescue Mission */ + {0x4B051022, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Shooting Gallery */ + {0xA908CFF5, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Spacegun */ + {0x5359762D, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Wanted */ + {0x0CA95637, 0, 0, SYSTEM_LIGHTPHASER, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Laser Ghost */ + + /* games requiring Sega Paddle */ + {0xF9DBB533, 0, 1, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Alex Kidd BMX Trial */ + {0xA6FA42D0, 0, 1, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Galactic Protector */ + {0x29BC7FAD, 0, 1, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Megumi Rescue */ + {0x315917D4, 0, 0, SYSTEM_PADDLE, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Woody Pop */ + + /* games requiring Sega Sport Pad */ + {0x0CB7E21F, 0, 0, SYSTEM_SPORTSPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Great Ice Hockey */ + {0xE42E4998, 0, 0, SYSTEM_SPORTSPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Sports Pad Football */ + {0x41C948BF, 0, 0, SYSTEM_SPORTSPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Sports Pad Soccer */ + + /* games supporting YM2413 FM */ + {0x1C951F8E, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* After Burner */ + {0xC13896D5, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Alex Kidd: The Lost Stars */ + {0x5CBFE997, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Alien Syndrome */ + {0xBBA2FE98, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Altered Beast */ + {0xFF614EB3, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Aztec Adventure */ + {0x3084CF11, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Bomber Raid */ + {0xAC6009A7, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* California Games */ + {0xA4852757, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Captain Silver */ + {0xB81F6FA5, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Captain Silver (U) */ + {0x3CFF6E80, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Casino Games */ + {0xE7F62E6D, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Cloud Master */ + {0x908E7524, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Cyborg Hunter */ + {0xA55D89F3, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Double Dragon */ + {0xB8B141F9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Fantasy Zone II */ + {0xD29889AD, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Fantasy Zone: The Maze */ + {0xA4AC35D8, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Galaxy Force */ + {0x6C827520, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Galaxy Force (U) */ + {0x1890F407, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Game Box Série Esportes Radicais (BR) */ + {0xB746A6F5, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Global Defense */ + {0x91A0FC4E, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Global Defense [Proto] */ + {0x48651325, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Golfamania */ + {0x5DABFDC3, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Golfamania [Proto] */ + {0xA51376FE, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Golvellius - Valley of Doom */ + {0x98E4AE4A, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Great Golf */ + {0x516ED32E, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Kenseiden */ + {0xE8511B08, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Lord of The Sword */ + {0x0E333B6E, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Miracle Warriors - Seal of The Dark Lord */ + {0x301A59AA, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Miracle Warriors - Seal of The Dark Lord [Proto] */ + {0x01D67C0B, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Mônica no Castelo do Dragão (BR) */ + {0x5589D8D2, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Out Run */ + {0xE030E66C, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Parlour Games */ + {0xF97E9875, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Penguin Land */ + {0x4077EFD9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Power Strike */ + {0xBB54B6B0, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* R-Type */ + {0x42FC47EE, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Rampage */ + {0xC547EB1B, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Rastan */ + {0x9A8B28EC, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Scramble Spirits */ + {0xAAB67EC3, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Shanghai */ + {0x0C6FAC4E, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Shinobi */ + {0x4752CAE7, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* SpellCaster */ + {0x1A390B93, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Tennis Ace */ + {0xAE920E4B, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Thunder Blade */ + {0x51BD14BE, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Time Soldiers */ + {0x22CCA9BB, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Turma da Mônica em: O Resgate (BR) */ + {0xB52D60C8, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Ultima IV */ + {0xDE9F8517, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Ultima IV [Proto] */ + {0xDFB0B161, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Vigilante */ + {0x679E1676, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Wonder Boy III: The Dragon's Trap */ + {0x8CBEF0C1, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Wonder Boy in Monster Land */ + {0x2F2E3BC9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Zillion II - The Tri Formation */ + {0x48D44A13, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_NONE, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* BIOS (J) */ + {0xD8C4165B, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Aleste */ + {0x4CC11DF9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Alien Syndrome (J) */ + {0xE421E466, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Chouon Senshi Borgman */ + {0x2BCDB8FA, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Doki Doki Penguin Land - Uchuu-Daibouken */ + {0x56BD2455, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Doki Doki Penguin Land - Uchuu-Daibouken [Proto] */ + {0xC722FB42, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Fantasy Zone II (J) */ + {0x7ABC70E9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Family Games (Party Games) */ + {0x6586BD1F, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Masters Golf */ + {0x4847BC91, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Masters Golf [Proto] */ + {0xB9FDF6D9, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Haja no Fuuin */ + {0x955A009E, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Hoshi wo Sagashite */ + {0x05EA5353, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Kenseiden (J) */ + {0xD11D32E4, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Kujakuou */ + {0xAA7D6F45, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Lord of Sword */ + {0xBF0411AD, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Maou Golvellius */ + {0x21A21352, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Maou Golvellius [Proto] */ + {0x5B5F9106, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Nekyuu Kousien */ + {0xBEA27D5C, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Opa Opa */ + {0x6605D36A, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Phantasy Star (J) */ + {0xE1FFF1BB, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Shinobi (J) */ + {0x11645549, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Solomon no Kagi - Oujo Rihita no Namida */ + {0x7E0EF8CB, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Super Racing */ + {0xB1DA6A30, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Super Wonder Boy Monster World */ + {0x8132AB2C, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Tensai Bakabon */ + {0xC0CE19B1, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS, REGION_JAPAN_NTSC}, /* Thunder Blade (J) */ + {0x07301F83, 0, 1, SYSTEM_MS_GAMEPAD, MAPPER_SEGA, SYSTEM_PBC, REGION_JAPAN_NTSC} /* Phantasy Star [Megadrive] (J) */ +}; + +/* Cartridge & BIOS ROM hardware */ +static romhw_t cart_rom; +static romhw_t bios_rom; + +/* Current slot */ +static struct +{ + uint8 *rom; + uint8 *fcr; + uint8 mapper; + uint8 pages; +} slot; + +/* Function prototypes */ +static void mapper_reset(void); +static void mapper_8k_w(int offset, unsigned int data); +static void mapper_16k_w(int offset, unsigned int data); +static void write_mapper_none(unsigned int address, unsigned char data); +static void write_mapper_sega(unsigned int address, unsigned char data); +static void write_mapper_codies(unsigned int address, unsigned char data); +static void write_mapper_korea(unsigned int address, unsigned char data); +static void write_mapper_korea_8k(unsigned int address, unsigned char data); +static void write_mapper_korea_16k(unsigned int address, unsigned char data); +static void write_mapper_msx(unsigned int address, unsigned char data); +static void write_mapper_multi(unsigned int address, unsigned char data); +static void write_mapper_93c46(unsigned int address, unsigned char data); +static void write_mapper_terebi(unsigned int address, unsigned char data); +static unsigned char read_mapper_93c46(unsigned int address); +static unsigned char read_mapper_terebi(unsigned int address); +static unsigned char read_mapper_korea_8k(unsigned int address); +static unsigned char read_mapper_default(unsigned int address); + +void sms_cart_init(void) +{ + int i; + + /* game CRC */ + uint32 crc = crc32(0, cart.rom, cart.romsize); + + /* use Master System controller by default */ + uint8 device = SYSTEM_MS_GAMEPAD; + + /* unmapped memory return $FF on read (mapped to unused cartridge areas $510000-$5103FF & $510400-$5107FF) */ + memset(cart.rom + 0x510000, 0xFF, 0x800); + + /* default cartridge ROM mapper */ + cart_rom.mapper = (cart.romsize > 0xC000) ? MAPPER_SEGA : MAPPER_NONE; + + /* disable 3-D Glasses by default */ + cart.special = 0; + + /* YM2413 chip in AUTO mode */ + if (config.ym2413 & 2) + { + if ((system_hw & SYSTEM_SMS) && (region_code == REGION_JAPAN_NTSC)) + { + /* japanese Master System has built-in FM chip */ + config.ym2413 = 3; + } + else + { + /* by default, FM chip is disabled */ + config.ym2413 = 2; + } + } + + /* auto-detect game settings */ + for (i=0; i> 10; + } + else if (cart_rom.mapper & MAPPER_KOREA_8K) + { + /* 8k ROM banks */ + cart_rom.pages = (cart.romsize + (1 << 13) - 1) >> 13; + } + else + { + /* 16k ROM banks */ + cart_rom.pages = (cart.romsize + (1 << 14) - 1) >> 14; + } + + /* initialize extra hardware */ + if (cart_rom.mapper == MAPPER_93C46) + { + /* 93C46 eeprom */ + eeprom_93c_init(); + } + else if (cart_rom.mapper == MAPPER_TEREBI) + { + /* Terebi Oekaki tablet */ + cart.special |= HW_TEREBI_OEKAKI; + } + + /* initialize SRAM */ + sram_init(); + + /* enable cartridge backup memory by default */ + sram.on = 1; + + /* save current settings */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force port A & port B configuration */ + input.system[0] = device; + input.system[1] = SYSTEM_MS_GAMEPAD; + + /* default gun offset */ + input.x_offset = 20; + input.y_offset = 0; + + /* SpaceGun & Gangster Town use different gun offset */ + if ((crc == 0x5359762D) || (crc == 0x5FC74D2A)) + { + input.x_offset = 16; + } + + /* BIOS support */ + if (config.bios & 1) + { + /* load BIOS file */ + int bios_size = load_bios(); + + if (bios_size > 0xC000) + { + /* assume SEGA mapper if BIOS ROM is larger than 48k */ + bios_rom.mapper = MAPPER_SEGA; + bios_rom.pages = bios_size >> 14; + } + else if (bios_size >= 0) + { + /* default BIOS ROM mapper */ + bios_rom.mapper = MAPPER_NONE; + bios_rom.pages = bios_size >> 10; + } + + /* unload cartridge if required & BIOS ROM is loaded */ + if (!(config.bios & 2) && bios_rom.pages) + { + cart_rom.pages = 0; + } + } + else + { + /* mark Master System & Game Gear BIOS as unloaded */ + system_bios &= ~(SYSTEM_SMS | SYSTEM_GG); + + /* BIOS ROM is disabled */ + bios_rom.pages = 0; + } +} + +void sms_cart_reset(void) +{ + /* reset BIOS ROM paging (SEGA mapper by default) */ + bios_rom.fcr[0] = 0; + bios_rom.fcr[1] = 0; + bios_rom.fcr[2] = 1; + bios_rom.fcr[3] = 2; + + /* reset cartridge ROM paging */ + switch (cart_rom.mapper) + { + case MAPPER_SEGA: + case MAPPER_SEGA_X: + cart_rom.fcr[0] = 0; + cart_rom.fcr[1] = 0; + cart_rom.fcr[2] = 1; + cart_rom.fcr[3] = 2; + break; + + case MAPPER_KOREA_8K: + case MAPPER_MSX: + case MAPPER_MSX_NEMESIS: + cart_rom.fcr[0] = 0; + cart_rom.fcr[1] = 0; + cart_rom.fcr[2] = 0; + cart_rom.fcr[3] = 0; + break; + + default: + cart_rom.fcr[0] = 0; + cart_rom.fcr[1] = 0; + cart_rom.fcr[2] = 1; + cart_rom.fcr[3] = 0; + break; + } + + /* check if BIOS is larger than 1k */ + if (bios_rom.pages > 1) + { + /* enable BIOS ROM */ + slot.rom = cart.rom + 0x400000; + slot.fcr = bios_rom.fcr; + slot.mapper = bios_rom.mapper; + slot.pages = bios_rom.pages; + } + else + { + /* enable cartridge ROM */ + slot.rom = cart.rom; + slot.fcr = cart_rom.fcr; + slot.mapper = cart_rom.mapper; + slot.pages = cart_rom.pages; + + /* force Memory Control register value in RAM (usually set by Master System BIOS) */ + if (system_hw & SYSTEM_SMS) + { + work_ram[0] = 0xA8; + } + } + + /* reset Memory Control register (RAM & I/O are enabled, either BIOS or Cartridge ROM are enabled) */ + io_reg[0x0E] = bios_rom.pages ? 0xE0 : 0xA8; + + /* reset Z80 memory map */ + mapper_reset(); + + /* 1k BIOS special case (Majesco GG) */ + if (bios_rom.pages == 1) + { + /* BIOS ROM is mapped to $0000-$03FF */ + z80_readmap[0] = cart.rom + 0x400000; + } +} + +void sms_cart_switch(uint8 mode) +{ + /* by default, disable cartridge & BIOS ROM */ + slot.pages = 0; + + /* cartridge ROM enabled ? */ + if (mode & 0x40) + { + /* check if cartridge is loaded */ + if (cart_rom.pages) + { + /* map cartridge ROM */ + slot.rom = cart.rom; + slot.fcr = cart_rom.fcr; + slot.mapper = cart_rom.mapper; + slot.pages = cart_rom.pages; + } + } + else + { + /* BIOS ROM enabled ? */ + if (mode & 0x08) + { + /* check if BIOS ROM is larger than 1K */ + if (bios_rom.pages > 1) + { + /* map BIOS ROM */ + slot.rom = cart.rom + 0x400000; + slot.fcr = bios_rom.fcr; + slot.mapper = bios_rom.mapper; + slot.pages = bios_rom.pages; + } + else + { + /* by default, map cartridge ROM */ + slot.rom = cart.rom; + slot.fcr = cart_rom.fcr; + slot.mapper = cart_rom.mapper; + slot.pages = cart_rom.pages; + } + } + + /* assume only BIOS would disable cartridge slot */ + if (!bios_rom.pages) + { + /* max. BIOS ROM size supported is 1MB */ + if (cart.romsize <= 0x100000) + { + /* copy to BIOS ROM */ + memcpy(cart.rom + 0x400000, cart.rom, cart.romsize); + memcpy(bios_rom.fcr, cart_rom.fcr, 4); + bios_rom.mapper = cart_rom.mapper; + bios_rom.pages = cart_rom.pages; + + /* unload cartridge */ + cart_rom.pages = 0; + } + } + } + + /* reset Z80 memory map */ + mapper_reset(); + + /* 1k BIOS special case (Majesco GG) */ + if ((bios_rom.pages == 1) && ((mode & 0x48) == 0x08)) + { + /* BIOS ROM is mapped to $0000-$03FF */ + z80_readmap[0] = cart.rom + 0x400000; + } +} + +int sms_cart_region_detect(void) +{ + int i; + + /* compute CRC */ + uint32 crc = crc32(0, cart.rom, cart.romsize); + + /* Turma da Mônica em: O Resgate & Wonder Boy III enable FM support on japanese hardware only */ + if (config.ym2413 && ((crc == 0x22CCA9BB) || (crc == 0x679E1676))) + { + return REGION_JAPAN_NTSC; + } + + /* game database */ + for (i=0; i> 10][address & 0x03FF] = data; +} + +static void write_mapper_sega(unsigned int address, unsigned char data) +{ + if (address >= 0xFFFC) + { + mapper_16k_w(address & 3, data); + } + + z80_writemap[address >> 10][address & 0x03FF] = data; +} + +static void write_mapper_codies(unsigned int address, unsigned char data) +{ + if (address == 0x0000) + { + mapper_16k_w(1,data); + return; + } + + if (address == 0x4000) + { + mapper_16k_w(2,data); + return; + } + + if (address == 0x8000) + { + mapper_16k_w(3,data); + return; + } + + z80_writemap[address >> 10][address & 0x03FF] = data; +} + +static void write_mapper_multi(unsigned int address, unsigned char data) +{ + if (address == 0x3FFE) + { + mapper_16k_w(1,data); + return; + } + + if (address == 0x7FFF) + { + mapper_16k_w(2,data); + return; + } + + if (address == 0xBFFF) + { + mapper_16k_w(3,(slot.fcr[1] & 0x30) + data); + return; + } + + z80_writemap[address >> 10][address & 0x03FF] = data; +} + +static void write_mapper_korea(unsigned int address, unsigned char data) +{ + if (address == 0xA000) + { + mapper_16k_w(3,data); + return; + } + + z80_writemap[address >> 10][address & 0x03FF] = data; +} + +static void write_mapper_msx(unsigned int address, unsigned char data) +{ + if (address <= 0x0003) + { + mapper_8k_w(address,data); + return; + } + + z80_writemap[address >> 10][address & 0x03FF] = data; +} + +static void write_mapper_korea_8k(unsigned int address, unsigned char data) +{ + if (address == 0x4000) + { + mapper_8k_w(2,data); + return; + } + + if (address == 0x6000) + { + mapper_8k_w(3,data); + return; + } + + if (address == 0x8000) + { + mapper_8k_w(0,data); + return; + } + + if (address == 0xA000) + { + mapper_8k_w(1,data); + return; + } + + if (address == 0xFFFE) + { + mapper_8k_w(2,(data << 1) & 0xFF); + mapper_8k_w(3,(1 + (data << 1)) & 0xFF); + } + else if (address == 0xFFFF) + { + mapper_8k_w(0,(data << 1) & 0xFF); + mapper_8k_w(1,(1 + (data << 1)) & 0xFF); + } + + z80_writemap[address >> 10][address & 0x03FF] = data; +} + +static void write_mapper_korea_16k(unsigned int address, unsigned char data) +{ + if (address == 0x4000) + { + mapper_16k_w(2,data); + return; + } + + if (address == 0x8000) + { + mapper_16k_w(3,data); + return; + } + + /* SEGA mapper compatibility */ + if (address >= 0xFFFC) + { + mapper_16k_w(address & 3, data); + } + + z80_writemap[address >> 10][address & 0x03FF] = data; +} + +static void write_mapper_93c46(unsigned int address, unsigned char data) +{ + /* EEPROM serial input */ + if ((address == 0x8000) && eeprom_93c.enabled) + { + eeprom_93c_write(data); + return; + } + + /* EEPROM ctrl */ + if (address == 0xFFFC) + { + /* enable/disable EEPROM */ + eeprom_93c.enabled = data & 0x08; + + if (data & 0x80) + { + /* reset EEPROM */ + eeprom_93c_init(); + } + } + + /* SEGA mapper compatibility */ + if (address > 0xFFFC) + { + mapper_16k_w(address & 3, data); + } + + z80_writemap[address >> 10][address & 0x03FF] = data; +} + +static void write_mapper_terebi(unsigned int address, unsigned char data) +{ + if (address == 0x6000) + { + terebi_oekaki_write(data); + return; + } + + z80_writemap[address >> 10][address & 0x03FF] = data; +} + +static unsigned char read_mapper_93c46(unsigned int address) +{ + if ((address == 0x8000) && eeprom_93c.enabled) + { + return eeprom_93c_read(); + } + + return z80_readmap[address >> 10][address & 0x03FF]; +} + +static unsigned char read_mapper_terebi(unsigned int address) +{ + if (address == 0x8000) + { + return (terebi_oekaki_read() >> 8); + } + + if (address == 0xA000) + { + return (terebi_oekaki_read() & 0xFF); + } + + return z80_readmap[address >> 10][address & 0x03FF]; +} + +static unsigned char read_mapper_korea_8k(unsigned int address) +{ + unsigned char data = z80_readmap[address >> 10][address & 0x03FF]; + + /* 16k page */ + unsigned char page = address >> 14; + + /* $4000-$7FFFF and $8000-$BFFF area are protected */ + if (((page == 1) && (slot.fcr[2] & 0x80)) || ((page == 2) && (slot.fcr[0] & 0x80))) + { + /* bit-swapped value */ + data = (((data >> 7) & 0x01) | ((data >> 5) & 0x02) | + ((data >> 3) & 0x04) | ((data >> 1) & 0x08) | + ((data << 1) & 0x10) | ((data << 3) & 0x20) | + ((data << 5) & 0x40) | ((data << 7) & 0x80)); + } + + return data; +} + +static unsigned char read_mapper_default(unsigned int address) +{ + return z80_readmap[address >> 10][address & 0x03FF]; +} diff --git a/genplus-gx/core/cart_hw/sms_cart.h b/genplus-gx/core/cart_hw/sms_cart.h new file mode 100644 index 0000000000..36d51c93c9 --- /dev/null +++ b/genplus-gx/core/cart_hw/sms_cart.h @@ -0,0 +1,56 @@ +/**************************************************************************** + * Genesis Plus + * SG-1000, Master System & Game Gear cartridge hardware support + * + * Copyright (C) 2007-2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _SMS_CART_H_ +#define _SMS_CART_H_ + +/* Special hardware */ +#define HW_3D_GLASSES 0x01 +#define HW_TEREBI_OEKAKI 0x02 + +/* Function prototypes */ +extern void sms_cart_init(void); +extern void sms_cart_reset(void); +extern void sms_cart_switch(uint8 mode); +extern int sms_cart_region_detect(void); +extern int sms_cart_context_save(uint8 *state); +extern int sms_cart_context_load(uint8 *state); + +#endif + + diff --git a/genplus-gx/core/cart_hw/sram.c b/genplus-gx/core/cart_hw/sram.c new file mode 100644 index 0000000000..ed8bea9067 --- /dev/null +++ b/genplus-gx/core/cart_hw/sram.c @@ -0,0 +1,221 @@ +/*************************************************************************************** + * Genesis Plus + * Backup RAM support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +T_SRAM sram; + +/**************************************************************************** + * A quick guide to external RAM on the Genesis + * + * The external RAM definition is held at offset 0x1b0 of the ROM header. + * + * 1B0h: dc.b 'RA', %1x1yz000, %abc00000 + * 1B4h: dc.l RAM start address + * 1B8h: dc.l RAM end address + * x 1 for BACKUP (not volatile), 0 for volatile RAM + * yz 10 if even address only + * 11 if odd address only + * 00 if both even and odd address + * 01 others (serial EEPROM, RAM with 4-bit data bus, etc) + * abc 001 if SRAM + * 010 if EEPROM (serial or parallel) + * other values unused + * + * Assuming max. 64k backup RAM throughout + ****************************************************************************/ +void sram_init() +{ + memset(&sram, 0, sizeof (T_SRAM)); + + /* backup RAM data is stored above cartridge ROM area, at $800000-$80FFFF (max. 64K) */ + if (cart.romsize > 0x800000) return; + sram.sram = cart.rom + 0x800000; + + /* initialize Backup RAM */ + memset(sram.sram, 0xFF, 0x10000); + sram.crc = crc32(0, sram.sram, 0x10000); + + /* retrieve informations from header */ + if ((READ_BYTE(cart.rom,0x1b0) == 0x52) && (READ_BYTE(cart.rom,0x1b1) == 0x41)) + { + /* backup RAM detected */ + sram.detected = 1; + + /* enable backup RAM */ + sram.on = 1; + + /* retrieve backup RAM start & end addresses */ + sram.start = READ_WORD_LONG(cart.rom, 0x1b4); + sram.end = READ_WORD_LONG(cart.rom, 0x1b8); + + /* autodetect games with wrong header infos */ + if (strstr(rominfo.product,"T-26013") != NULL) + { + /* Psy-O-Blade (wrong header) */ + sram.start = 0x200001; + sram.end = 0x203fff; + } + + /* fixe games indicating internal RAM as volatile external RAM (Feng Kuang Tao Hua Yuan) */ + else if (sram.start == 0xff0000) + { + /* backup RAM should be disabled */ + sram.on = 0; + } + + /* fixe other bad header informations */ + else if ((sram.start > sram.end) || ((sram.end - sram.start) >= 0x10000)) + { + sram.end = sram.start + 0xffff; + } + } + else + { + /* autodetect games with missing header infos */ + if (strstr(rominfo.product,"T-50086") != NULL) + { + /* PGA Tour Golf */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x203fff; + } + else if (strstr(rominfo.product,"ACLD007") != NULL) + { + /* Winter Challenge */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x200fff; + } + else if (strstr(rominfo.product,"T-50286") != NULL) + { + /* Buck Rogers - Countdown to Doomsday */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x203fff; + } + else if (((rominfo.realchecksum == 0xaeaa) || (rominfo.realchecksum == 0x8dba)) && + (rominfo.checksum == 0x8104)) + { + /* Xin Qigai Wangzi (use uncommon area) */ + sram.on = 1; + sram.start = 0x400001; + sram.end = 0x40ffff; + } + else if ((strstr(rominfo.ROMType,"SF") != NULL) && (strstr(rominfo.product,"001") != NULL)) + { + /* SF-001 */ + sram.on = 1; + if (rominfo.checksum == 0x3e08) + { + /* last revision (use bankswitching) */ + sram.start = 0x3c0001; + sram.end = 0x3cffff; + } + else + { + /* older revisions (use uncommon area) */ + sram.start = 0x400001; + sram.end = 0x40ffff; + } + } + else if ((strstr(rominfo.ROMType,"SF") != NULL) && (strstr(rominfo.product,"004") != NULL)) + { + /* SF-004 (use bankswitching) */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x203fff; + } + else if (strstr(rominfo.international,"SONIC & KNUCKLES") != NULL) + { + /* Sonic 3 & Knuckles combined ROM */ + if (cart.romsize == 0x400000) + { + /* Sonic & Knuckle does not have backup RAM but can access FRAM from Sonic 3 cartridge */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x203fff; + } + } + + /* auto-detect games which need disabled backup RAM */ + else if (strstr(rominfo.product,"T-113016") != NULL) + { + /* Pugsy (does not have backup RAM but tries writing outside ROM area as copy protection) */ + sram.on = 0; + } + else if (strstr(rominfo.international,"SONIC THE HEDGEHOG 2") != NULL) + { + /* Sonic the Hedgehog 2 (does not have backup RAM) */ + /* this prevents backup RAM from being mapped in place of mirrored ROM when using S&K LOCK-ON feature */ + sram.on = 0; + } + + /* by default, enable backup RAM for ROM smaller than 2MB */ + else if (cart.romsize <= 0x200000) + { + /* 64KB static RAM mapped to $200000-$20ffff */ + sram.start = 0x200000; + sram.end = 0x20ffff; + sram.on = 1; + } + } +} + +unsigned int sram_read_byte(unsigned int address) +{ + return sram.sram[address & 0xffff]; +} + +unsigned int sram_read_word(unsigned int address) +{ + address &= 0xfffe; + return (sram.sram[address + 1] | (sram.sram[address] << 8)); +} + +void sram_write_byte(unsigned int address, unsigned int data) +{ + sram.sram[address & 0xffff] = data; +} + +void sram_write_word(unsigned int address, unsigned int data) +{ + address &= 0xfffe; + sram.sram[address] = data >> 8; + sram.sram[address + 1] = data & 0xff; +} diff --git a/genplus-gx/core/cart_hw/sram.h b/genplus-gx/core/cart_hw/sram.h new file mode 100644 index 0000000000..64934cab6e --- /dev/null +++ b/genplus-gx/core/cart_hw/sram.h @@ -0,0 +1,63 @@ +/*************************************************************************************** + * Genesis Plus + * Backup RAM support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _SRAM_H_ +#define _SRAM_H_ + +typedef struct +{ + uint8 detected; + uint8 on; + uint8 custom; + uint32 start; + uint32 end; + uint32 crc; + uint8 *sram; +} T_SRAM; + +/* Function prototypes */ +extern void sram_init(); +extern unsigned int sram_read_byte(unsigned int address); +extern unsigned int sram_read_word(unsigned int address); +extern void sram_write_byte(unsigned int address, unsigned int data); +extern void sram_write_word(unsigned int address, unsigned int data); + +/* global variables */ +extern T_SRAM sram; + +#endif diff --git a/genplus-gx/core/cart_hw/svp/imageformat.txt b/genplus-gx/core/cart_hw/svp/imageformat.txt new file mode 100644 index 0000000000..2d453b3330 --- /dev/null +++ b/genplus-gx/core/cart_hw/svp/imageformat.txt @@ -0,0 +1,68 @@ + +vscroll: 1 (0); 209 (26) - alternates every 4 frames +vram range for patterns: 0000-999f (low scr 0000-395f,72e0-999f; high 3980-999f) +name table address: c000 +seen DMAs (in order): + [300002-3026c3]->[0020-26e1] len 4961 + [3026c2-303943]->[26e0-3961] len 2369 + [303942-306003]->[72e0-99a1] len 4961 + --- + [306002-3086c3]->[3980-6041] len 4961 + [3086c2-309943]->[6040-72c1] len 2369 + [309942-30c003]->[72e0-99a2] len 4961 +tile arrangement: + +000: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 +001: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 +002: 001 003 005 007 009 00b 00d 00f 011 013 015 017 019 01b 01d 01f 021 023 025 027 029 02b 02d 02f 031 033 035 037 039 03b 03d 03f +003: 002 004 006 008 00a 00c 00e 010 012 014 016 018 01a 01c 01e 020 022 024 026 028 02a 02c 02e 030 032 034 036 038 03a 03c 03e 040 +004: 041 043 045 047 049 04b 04d 04f 051 053 055 057 059 05b 05d 05f 061 063 065 067 069 06b 06d 06f 071 073 075 077 079 07b 07d 07f +005: 042 044 046 048 04a 04c 04e 050 052 054 056 058 05a 05c 05e 060 062 064 066 068 06a 06c 06e 070 072 074 076 078 07a 07c 07e 080 +006: 081 083 085 087 089 08b 08d 08f 091 093 095 097 099 09b 09d 09f 0a1 0a3 0a5 0a7 0a9 0ab 0ad 0af 0b1 0b3 0b5 0b7 0b9 0bb 0bd 0bf +007: 082 084 086 088 08a 08c 08e 090 092 094 096 098 09a 09c 09e 0a0 0a2 0a4 0a6 0a8 0aa 0ac 0ae 0b0 0b2 0b4 0b6 0b8 0ba 0bc 0be 0c0 +008: 0c1 0c3 0c5 0c7 0c9 0cb 0cd 0cf 0d1 0d3 0d5 0d7 0d9 0db 0dd 0df 0e1 0e3 0e5 0e7 0e9 0eb 0ed 0ef 0f1 0f3 0f5 0f7 0f9 0fb 0fd 0ff +009: 0c2 0c4 0c6 0c8 0ca 0cc 0ce 0d0 0d2 0d4 0d6 0d8 0da 0dc 0de 0e0 0e2 0e4 0e6 0e8 0ea 0ec 0ee 0f0 0f2 0f4 0f6 0f8 0fa 0fc 0fe 100 +010: 101 103 105 107 109 10b 10d 10f 111 113 115 117 119 11b 11d 11f 121 123 125 127 129 12b 12d 12f 131 133 135 137 139 13b 13d 13f +011: 102 104 106 108 10a 10c 10e 110 112 114 116 118 11a 11c 11e 120 122 124 126 128 12a 12c 12e 130 132 134 136 138 13a 13c 13e 140 +012: 141 143 145 147 149 14b 14d 14f 151 153 155 157 159 15b 15d 15f 161 163 165 167 169 16b 16d 16f 171 173 175 177 179 17b 17d 17f +013: 142 144 146 148 14a 14c 14e 150 152 154 156 158 15a 15c 15e 160 162 164 166 168 16a 16c 16e 170 172 174 176 178 17a 17c 17e 180 +014: 181 183 185 187 189 18b 18d 18f 191 193 195 197 199 19b 19d 19f 1a1 1a3 1a5 1a7 1a9 1ab 1ad 1af 1b1 1b3 1b5 1b7 1b9 1bb 1bd 1bf +015: 182 184 186 188 18a 18c 18e 190 192 194 196 198 19a 19c 19e 1a0 1a2 1a4 1a6 1a8 1aa 1ac 1ae 1b0 1b2 1b4 1b6 1b8 1ba 1bc 1be 1c0 +016: 1c1 1c3 1c5 1c7 1c9 397 399 39b 39d 39f 3a1 3a3 3a5 3a7 3a9 3ab 3ad 3af 3b1 3b3 3b5 3b7 3b9 3bb 3bd 3bf 3c1 3c3 3c5 3c7 3c9 3cb +017: 1c2 1c4 1c6 1c8 1ca 398 39a 39c 39e 3a0 3a2 3a4 3a6 3a8 3aa 3ac 3ae 3b0 3b2 3b4 3b6 3b8 3ba 3bc 3be 3c0 3c2 3c4 3c6 3c8 3ca 3cc +018: 3cd 3cf 3d1 3d3 3d5 3d7 3d9 3db 3dd 3df 3e1 3e3 3e5 3e7 3e9 3eb 3ed 3ef 3f1 3f3 3f5 3f7 3f9 3fb 3fd 3ff 401 403 405 407 409 40b +019: 3ce 3d0 3d2 3d4 3d6 3d8 3da 3dc 3de 3e0 3e2 3e4 3e6 3e8 3ea 3ec 3ee 3f0 3f2 3f4 3f6 3f8 3fa 3fc 3fe 400 402 404 406 408 40a 40c +020: 40d 40f 411 413 415 417 419 41b 41d 41f 421 423 425 427 429 42b 42d 42f 431 433 435 437 439 43b 43d 43f 441 443 445 447 449 44b +021: 40e 410 412 414 416 418 41a 41c 41e 420 422 424 426 428 42a 42c 42e 430 432 434 436 438 43a 43c 43e 440 442 444 446 448 44a 44c +022: 44d 44f 451 453 455 457 459 45b 45d 45f 461 463 465 467 469 46b 46d 46f 471 473 475 477 479 47b 47d 47f 481 483 485 487 489 48b +023: 44e 450 452 454 456 458 45a 45c 45e 460 462 464 466 468 46a 46c 46e 470 472 474 476 478 47a 47c 47e 480 482 484 486 488 48a 48c +024: 48d 48f 491 493 495 497 499 49b 49d 49f 4a1 4a3 4a5 4a7 4a9 4ab 4ad 4af 4b1 4b3 4b5 4b7 4b9 4bb 4bd 4bf 4c1 4c3 4c5 4c7 4c9 4cb +025: 48e 490 492 494 496 498 49a 49c 49e 4a0 4a2 4a4 4a6 4a8 4aa 4ac 4ae 4b0 4b2 4b4 4b6 4b8 4ba 4bc 4be 4c0 4c2 4c4 4c6 4c8 4ca 4cc +026: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 +027: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 +028: 1cc 1ce 1d0 1d2 1d4 1d6 1d8 1da 1dc 1de 1e0 1e2 1e4 1e6 1e8 1ea 1ec 1ee 1f0 1f2 1f4 1f6 1f8 1fa 1fc 1fe 200 202 204 206 208 20a +029: 1cd 1cf 1d1 1d3 1d5 1d7 1d9 1db 1dd 1df 1e1 1e3 1e5 1e7 1e9 1eb 1ed 1ef 1f1 1f3 1f5 1f7 1f9 1fb 1fd 1ff 201 203 205 207 209 20b +030: 20c 20e 210 212 214 216 218 21a 21c 21e 220 222 224 226 228 22a 22c 22e 230 232 234 236 238 23a 23c 23e 240 242 244 246 248 24a +031: 20d 20f 211 213 215 217 219 21b 21d 21f 221 223 225 227 229 22b 22d 22f 231 233 235 237 239 23b 23d 23f 241 243 245 247 249 24b +032: 24c 24e 250 252 254 256 258 25a 25c 25e 260 262 264 266 268 26a 26c 26e 270 272 274 276 278 27a 27c 27e 280 282 284 286 288 28a +033: 24d 24f 251 253 255 257 259 25b 25d 25f 261 263 265 267 269 26b 26d 26f 271 273 275 277 279 27b 27d 27f 281 283 285 287 289 28b +034: 28c 28e 290 292 294 296 298 29a 29c 29e 2a0 2a2 2a4 2a6 2a8 2aa 2ac 2ae 2b0 2b2 2b4 2b6 2b8 2ba 2bc 2be 2c0 2c2 2c4 2c6 2c8 2ca +035: 28d 28f 291 293 295 297 299 29b 29d 29f 2a1 2a3 2a5 2a7 2a9 2ab 2ad 2af 2b1 2b3 2b5 2b7 2b9 2bb 2bd 2bf 2c1 2c3 2c5 2c7 2c9 2cb +036: 2cc 2ce 2d0 2d2 2d4 2d6 2d8 2da 2dc 2de 2e0 2e2 2e4 2e6 2e8 2ea 2ec 2ee 2f0 2f2 2f4 2f6 2f8 2fa 2fc 2fe 300 302 304 306 308 30a +037: 2cd 2cf 2d1 2d3 2d5 2d7 2d9 2db 2dd 2df 2e1 2e3 2e5 2e7 2e9 2eb 2ed 2ef 2f1 2f3 2f5 2f7 2f9 2fb 2fd 2ff 301 303 305 307 309 30b +038: 30c 30e 310 312 314 316 318 31a 31c 31e 320 322 324 326 328 32a 32c 32e 330 332 334 336 338 33a 33c 33e 340 342 344 346 348 34a +039: 30d 30f 311 313 315 317 319 31b 31d 31f 321 323 325 327 329 32b 32d 32f 331 333 335 337 339 33b 33d 33f 341 343 345 347 349 34b +040: 34c 34e 350 352 354 356 358 35a 35c 35e 360 362 364 366 368 36a 36c 36e 370 372 374 376 378 37a 37c 37e 380 382 384 386 388 38a +041: 34d 34f 351 353 355 357 359 35b 35d 35f 361 363 365 367 369 36b 36d 36f 371 373 375 377 379 37b 37d 37f 381 383 385 387 389 38b +042: 38c 38e 390 392 394 397 399 39b 39d 39f 3a1 3a3 3a5 3a7 3a9 3ab 3ad 3af 3b1 3b3 3b5 3b7 3b9 3bb 3bd 3bf 3c1 3c3 3c5 3c7 3c9 3cb +043: 38d 38f 391 393 395 398 39a 39c 39e 3a0 3a2 3a4 3a6 3a8 3aa 3ac 3ae 3b0 3b2 3b4 3b6 3b8 3ba 3bc 3be 3c0 3c2 3c4 3c6 3c8 3ca 3cc +044: 3cd 3cf 3d1 3d3 3d5 3d7 3d9 3db 3dd 3df 3e1 3e3 3e5 3e7 3e9 3eb 3ed 3ef 3f1 3f3 3f5 3f7 3f9 3fb 3fd 3ff 401 403 405 407 409 40b +045: 3ce 3d0 3d2 3d4 3d6 3d8 3da 3dc 3de 3e0 3e2 3e4 3e6 3e8 3ea 3ec 3ee 3f0 3f2 3f4 3f6 3f8 3fa 3fc 3fe 400 402 404 406 408 40a 40c +046: 40d 40f 411 413 415 417 419 41b 41d 41f 421 423 425 427 429 42b 42d 42f 431 433 435 437 439 43b 43d 43f 441 443 445 447 449 44b +047: 40e 410 412 414 416 418 41a 41c 41e 420 422 424 426 428 42a 42c 42e 430 432 434 436 438 43a 43c 43e 440 442 444 446 448 44a 44c +048: 44d 44f 451 453 455 457 459 45b 45d 45f 461 463 465 467 469 46b 46d 46f 471 473 475 477 479 47b 47d 47f 481 483 485 487 489 48b +049: 44e 450 452 454 456 458 45a 45c 45e 460 462 464 466 468 46a 46c 46e 470 472 474 476 478 47a 47c 47e 480 482 484 486 488 48a 48c +050: 48d 48f 491 493 495 497 499 49b 49d 49f 4a1 4a3 4a5 4a7 4a9 4ab 4ad 4af 4b1 4b3 4b5 4b7 4b9 4bb 4bd 4bf 4c1 4c3 4c5 4c7 4c9 4cb +051: 48e 490 492 494 496 498 49a 49c 49e 4a0 4a2 4a4 4a6 4a8 4aa 4ac 4ae 4b0 4b2 4b4 4b6 4b8 4ba 4bc 4be 4c0 4c2 4c4 4c6 4c8 4ca 4cc +052: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 +053: 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 diff --git a/genplus-gx/core/cart_hw/svp/ssp16.c b/genplus-gx/core/cart_hw/svp/ssp16.c new file mode 100644 index 0000000000..f2f648c0fd --- /dev/null +++ b/genplus-gx/core/cart_hw/svp/ssp16.c @@ -0,0 +1,1333 @@ +/* + basic, incomplete SSP160x (SSP1601?) interpreter + with SVP memory controller emu + + (c) Copyright 2008, Grazvydas "notaz" Ignotas + Free for non-commercial use. + + For commercial use, separate licencing terms must be obtained. + + Modified for Genesis Plus GX (Eke-Eke), added big endian support, fixed mode & addr +*/ + + +/* + * Register info + * + * 0. "-" + * size: 16 + * desc: Constant register with all bits set (0xffff). + * + * 1. "X" + * size: 16 + * desc: Generic register. When set, updates P (P = X * Y * 2) + * + * 2. "Y" + * size: 16 + * desc: Generic register. When set, updates P (P = X * Y * 2) + * + * 3. "A" + * size: 32 + * desc: Accumulator. + * + * 4. "ST" + * size: 16 + * desc: Status register. From MAME: bits 0-9 are CONTROL, other FLAG + * fedc ba98 7654 3210 + * 210 - RPL (?) "Loop size". If non-zero, makes (rX+) and (rX-) respectively + * modulo-increment and modulo-decrement. The value shows which + * power of 2 to use, i.e. 4 means modulo by 16. + * (e: fir16_32.sc, IIR_4B.SC, DECIM.SC) + * 43 - RB (?) + * 5 - GP0_0 (ST5?) Changed before acessing PM0 (affects banking?). + * 6 - GP0_1 (ST6?) Cleared before acessing PM0 (affects banking?). Set after. + * datasheet says these (5,6) bits correspond to hardware pins. + * 7 - IE (?) Not directly used by SVP code (never set, but preserved)? + * 8 - OP (?) Not used by SVP code (only cleared)? (MAME: saturated value + * (probably means clamping? i.e. 0x7ffc + 9 -> 0x7fff)) + * 9 - MACS (?) Not used by SVP code (only cleared)? (e: "mac shift") + * a - GPI_0 Interrupt 0 enable/status? + * b - GPI_1 Interrupt 1 enable/status? + * c - L L flag. Carry? + * d - Z Zero flag. + * e - OV Overflow flag. + * f - N Negative flag. + * seen directly changing code sequences: + * ldi ST, 0 ld A, ST ld A, ST ld A, ST ldi st, 20h + * ldi ST, 60h ori A, 60h and A, E8h and A, E8h + * ld ST, A ld ST, A ori 3 + * ld ST, A + * + * 5. "STACK" + * size: 16 + * desc: hw stack of 6 levels (according to datasheet) + * + * 6. "PC" + * size: 16 + * desc: Program counter. + * + * 7. "P" + * size: 32 + * desc: multiply result register. P = X * Y * 2 + * probably affected by MACS bit in ST. + * + * 8. "PM0" (PM from PMAR name from Tasco's docs) + * size: 16? + * desc: Programmable Memory access register. + * On reset, or when one (both?) GP0 bits are clear, + * acts as status for XST, mapped at 015004 at 68k side: + * bit0: ssp has written something to XST (cleared when 015004 is read) + * bit1: 68k has written something through a1500{0|2} (cleared on PM0 read) + * + * 9. "PM1" + * size: 16? + * desc: Programmable Memory access register. + * This reg. is only used as PMAR. + * + * 10. "PM2" + * size: 16? + * desc: Programmable Memory access register. + * This reg. is only used as PMAR. + * + * 11. "XST" + * size: 16? + * desc: eXternal STate. Mapped to a15000 and a15002 at 68k side. + * Can be programmed as PMAR? (only seen in test mode code) + * Affects PM0 when written to? + * + * 12. "PM4" + * size: 16? + * desc: Programmable Memory access register. + * This reg. is only used as PMAR. The most used PMAR by VR. + * + * 13. (unused by VR) + * + * 14. "PMC" (PMC from PMAC name from Tasco's docs) + * size: 32? + * desc: Programmable Memory access Control. Set using 2 16bit writes, + * first address, then mode word. After setting PMAC, PMAR sould + * be blind accessed (ld -, PMx or ld PMx, -) to program it for + * reading and writing respectively. + * Reading the register also shifts it's state (from "waiting for + * address" to "waiting for mode" and back). Reads always return + * address related to last PMx register accressed. + * (note: addresses do not wrap). + * + * 15. "AL" + * size: 16 + * desc: Accumulator Low. 16 least significant bits of accumulator. + * (normally reading acc (ld X, A) you get 16 most significant bits). + * + * + * There are 8 8-bit pointer registers rX. r0-r3 (ri) point to RAM0, r4-r7 (rj) point to RAM1. + * They can be accessed directly, or 2 indirection levels can be used [ (rX), ((rX)) ], + * which work similar to * and ** operators in C, only they use different memory banks and + * ((rX)) also does post-increment. First indirection level (rX) accesses RAMx, second accesses + * program memory at address read from (rX), and increments value in (rX). + * + * r0,r1,r2,r4,r5,r6 can be modified [ex: ldi r0, 5]. + * 3 modifiers can be applied (optional): + * + : post-increment [ex: ld a, (r0+) ]. Can be made modulo-increment by setting RPL bits in ST. + * - : post-decrement. Can be made modulo-decrement by setting RPL bits in ST (not sure). + * +!: post-increment, unaffected by RPL (probably). + * These are only used on 1st indirection level, so things like [ld a, ((r0+))] and [ld X, r6-] + * ar probably invalid. + * + * r3 and r7 are special and can not be changed (at least Samsung samples and SVP code never do). + * They are fixed to the start of their RAM banks. (They are probably changeable for ssp1605+, + * Samsung's old DSP page claims that). + * 1 of these 4 modifiers must be used (short form direct addressing?): + * |00: RAMx[0] [ex: (r3|00), 0] (based on sample code) + * |01: RAMx[1] + * |10: RAMx[2] ? maybe 10h? accortding to Div_c_dp.sc, 2 + * |11: RAMx[3] + * + * + * Instruction notes + * + * ld a, * doesn't affect flags! (e: A_LAW.SC, Div_c_dp.sc) + * + * mld (rj), (ri) [, b] + * operation: A = 0; P = (rj) * (ri) + * notes: based on IIR_4B.SC sample. flags? what is b??? + * + * mpya (rj), (ri) [, b] + * name: multiply and add? + * operation: A += P; P = (rj) * (ri) + * + * mpys (rj), (ri), b + * name: multiply and subtract? + * notes: not used by VR code. + * + * mod cond, op + * mod cond, shr does arithmetic shift + * + * 'ld -, AL' and probably 'ld AL, -' are for dummy assigns + * + * memory map: + * 000000 - 1fffff ROM, accessable by both + * 200000 - 2fffff unused? + * 300000 - 31ffff DRAM, both + * 320000 - 38ffff unused? + * 390000 - 3907ff IRAM. can only be accessed by ssp? + * 390000 - 39ffff similar mapping to "cell arrange" in Sega CD, 68k only? + * 3a0000 - 3affff similar mapping to "cell arrange" in Sega CD, a bit different + * + * 30fe02 - 0 if SVP busy, 1 if done (set by SVP, checked and cleared by 68k) + * 30fe06 - also sync related. + * 30fe08 - job number [1-12] for SVP. 0 means no job. Set by 68k, read-cleared by SVP. + * + * + figure out if 'op A, P' is 32bit (nearly sure it is) + * * does mld, mpya load their operands into X and Y? + * * OP simm + * + * Assumptions in this code + * P is not directly writeable + * flags correspond to full 32bit accumulator + * only Z and N status flags are emulated (others unused by SVP) + * modifiers for 'OP a, ri' are ignored (invalid?/not used by SVP) + * 'ld d, (a)' loads from program ROM + */ + +#include "shared.h" + + +#define u32 unsigned int + +/*#define USE_DEBUGGER*/ + +/* 0 */ +#define rX ssp->gr[SSP_X].byte.h +#define rY ssp->gr[SSP_Y].byte.h +#define rA ssp->gr[SSP_A].byte.h +#define rST ssp->gr[SSP_ST].byte.h /* 4 */ +#define rSTACK ssp->gr[SSP_STACK].byte.h +#define rPC ssp->gr[SSP_PC].byte.h +#define rP ssp->gr[SSP_P] +#define rPM0 ssp->gr[SSP_PM0].byte.h /* 8 */ +#define rPM1 ssp->gr[SSP_PM1].byte.h +#define rPM2 ssp->gr[SSP_PM2].byte.h +#define rXST ssp->gr[SSP_XST].byte.h +#define rPM4 ssp->gr[SSP_PM4].byte.h /* 12 */ +/* 13 */ +#define rPMC ssp->gr[SSP_PMC] /* will keep addr in .h, mode in .l */ +#define rAL ssp->gr[SSP_A].byte.l + +#define rA32 ssp->gr[SSP_A].v +#define rIJ ssp->ptr.r + +#define IJind (((op>>6)&4)|(op&3)) + +#define GET_PC() (PC - (unsigned short *)svp->iram_rom) +#define GET_PPC_OFFS() ((unsigned int)PC - (unsigned int)svp->iram_rom - 2) +#define SET_PC(d) PC = (unsigned short *)svp->iram_rom + d + +#define REG_READ(r) (((r) <= 4) ? ssp->gr[r].byte.h : read_handlers[r]()) +#define REG_WRITE(r,d) { \ + int r1 = r; \ + if (r1 >= 4) write_handlers[r1](d); \ + else if (r1 > 0) ssp->gr[r1].byte.h = d; \ +} + +/* flags */ +#define SSP_FLAG_L (1<<0xc) +#define SSP_FLAG_Z (1<<0xd) +#define SSP_FLAG_V (1<<0xe) +#define SSP_FLAG_N (1<<0xf) + +/* update ZN according to 32bit ACC. */ +#define UPD_ACC_ZN \ + rST &= ~(SSP_FLAG_Z|SSP_FLAG_N); \ + if (!rA32) rST |= SSP_FLAG_Z; \ + else rST |= (rA32>>16)&SSP_FLAG_N; + +/* it seems SVP code never checks for L and OV, so we leave them out. */ +/* rST |= (t>>4)&SSP_FLAG_L; */ +#define UPD_LZVN \ + rST &= ~(SSP_FLAG_L|SSP_FLAG_Z|SSP_FLAG_V|SSP_FLAG_N); \ + if (!rA32) rST |= SSP_FLAG_Z; \ + else rST |= (rA32>>16)&SSP_FLAG_N; + +/* standard cond processing. */ +/* again, only Z and N is checked, as SVP doesn't seem to use any other conds. */ +#define COND_CHECK \ + switch (op&0xf0) { \ + case 0x00: cond = 1; break; /* always true */ \ + case 0x50: cond = !((rST ^ (op<<5)) & SSP_FLAG_Z); break; /* Z matches f(?) bit */ \ + case 0x70: cond = !((rST ^ (op<<7)) & SSP_FLAG_N); break; /* N matches f(?) bit */ \ + default: break; \ + } + +/* ops with accumulator. */ +/* how is low word really affected by these? */ +/* nearly sure 'ld A' doesn't affect flags */ +#define OP_LDA(x) \ + rA = x + +#define OP_LDA32(x) \ + rA32 = x + +#define OP_SUBA(x) { \ + rA32 -= (x) << 16; \ + UPD_LZVN \ +} + +#define OP_SUBA32(x) { \ + rA32 -= (x); \ + UPD_LZVN \ +} + +#define OP_CMPA(x) { \ + u32 t = rA32 - ((x) << 16); \ + rST &= ~(SSP_FLAG_L|SSP_FLAG_Z|SSP_FLAG_V|SSP_FLAG_N); \ + if (!t) rST |= SSP_FLAG_Z; \ + else rST |= (t>>16)&SSP_FLAG_N; \ +} + +#define OP_CMPA32(x) { \ + u32 t = rA32 - (x); \ + rST &= ~(SSP_FLAG_L|SSP_FLAG_Z|SSP_FLAG_V|SSP_FLAG_N); \ + if (!t) rST |= SSP_FLAG_Z; \ + else rST |= (t>>16)&SSP_FLAG_N; \ +} + +#define OP_ADDA(x) { \ + rA32 += (x) << 16; \ + UPD_LZVN \ +} + +#define OP_ADDA32(x) { \ + rA32 += (x); \ + UPD_LZVN \ +} + +#define OP_ANDA(x) \ + rA32 &= (x) << 16; \ + UPD_ACC_ZN + +#define OP_ANDA32(x) \ + rA32 &= (x); \ + UPD_ACC_ZN + +#define OP_ORA(x) \ + rA32 |= (x) << 16; \ + UPD_ACC_ZN + +#define OP_ORA32(x) \ + rA32 |= (x); \ + UPD_ACC_ZN + +#define OP_EORA(x) \ + rA32 ^= (x) << 16; \ + UPD_ACC_ZN + +#define OP_EORA32(x) \ + rA32 ^= (x); \ + UPD_ACC_ZN + + +#define OP_CHECK32(OP) { \ + if ((op & 0x0f) == SSP_P) { /* A <- P */ \ + read_P(); /* update P */ \ + OP(rP.v); \ + break; \ + } \ + if ((op & 0x0f) == SSP_A) { /* A <- A */ \ + OP(rA32); \ + break; \ + } \ +} + + +static ssp1601_t *ssp = NULL; +static unsigned short *PC; +static int g_cycles; + +#ifdef USE_DEBUGGER +static int running = 0; +static int last_iram = 0; +#endif + +/* ----------------------------------------------------- */ +/* register i/o handlers */ + +/* 0-4, 13 */ +static u32 read_unknown(void) +{ +#ifdef LOG_SVP + elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME: unknown read @ %04x", GET_PPC_OFFS()); +#endif + return 0; +} + +static void write_unknown(u32 d) +{ +#ifdef LOG_SVP + elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME: unknown write @ %04x", GET_PPC_OFFS()); +#endif +} + +/* 4 */ +static void write_ST(u32 d) +{ + /* if ((rST ^ d) & 0x0007) elprintf(EL_SVP, "ssp RPL %i -> %i @ %04x", rST&7, d&7, GET_PPC_OFFS()); */ +#ifdef LOG_SVP + if ((rST ^ d) & 0x0f98) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME ST %04x -> %04x @ %04x", rST, d, GET_PPC_OFFS()); +#endif + rST = d; +} + +/* 5 */ +static u32 read_STACK(void) +{ + --rSTACK; + if ((short)rSTACK < 0) { + rSTACK = 5; +#ifdef LOG_SVP + elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME: stack underflow! (%i) @ %04x", rSTACK, GET_PPC_OFFS()); +#endif + } + return ssp->stack[rSTACK]; +} + +static void write_STACK(u32 d) +{ + if (rSTACK >= 6) { +#ifdef LOG_SVP + elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME: stack overflow! (%i) @ %04x", rSTACK, GET_PPC_OFFS()); +#endif + rSTACK = 0; + } + ssp->stack[rSTACK++] = d; +} + +/* 6 */ +static u32 read_PC(void) +{ + /* g_cycles--; */ + return GET_PC(); +} + +static void write_PC(u32 d) +{ + SET_PC(d); + g_cycles--; +} + +/* 7 */ +static u32 read_P(void) +{ + int m1 = (signed short)rX; + int m2 = (signed short)rY; + rP.v = (m1 * m2 * 2); + return rP.byte.h; +} + +/* ----------------------------------------------------- */ + +static int get_inc(int mode) +{ + int inc = (mode >> 11) & 7; + if (inc != 0) { + if (inc != 7) inc--; + /* inc = (1<<16) << inc; */ + inc = 1 << inc; /* 0 1 2 4 8 16 32 128 */ + if (mode & 0x8000) inc = -inc; /* decrement mode */ + } + return inc; +} + +#define overwite_write(dst, d) \ +{ \ + if (d & 0xf000) { dst &= ~0xf000; dst |= d & 0xf000; } \ + if (d & 0x0f00) { dst &= ~0x0f00; dst |= d & 0x0f00; } \ + if (d & 0x00f0) { dst &= ~0x00f0; dst |= d & 0x00f0; } \ + if (d & 0x000f) { dst &= ~0x000f; dst |= d & 0x000f; } \ +} + +static u32 pm_io(int reg, int write, u32 d) +{ + if (ssp->emu_status & SSP_PMC_SET) + { + /* this MUST be blind r or w */ + if ((*(PC-1) & 0xff0f) && (*(PC-1) & 0xfff0)) { +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: tried to set PM%i (%c) with non-blind i/o %08x @ %04x", + reg, write ? 'w' : 'r', rPMC.v, GET_PPC_OFFS()); +#endif + ssp->emu_status &= ~SSP_PMC_SET; + return 0; + } +#ifdef LOG_SVP + elprintf(EL_SVP, "PM%i (%c) set to %08x @ %04x", reg, write ? 'w' : 'r', rPMC.v, GET_PPC_OFFS()); +#endif + ssp->pmac[write][reg] = rPMC.v; + ssp->emu_status &= ~SSP_PMC_SET; +#ifdef LOG_SVP + if ((rPMC.v & 0x7f) == 0x1c && (rPMC.v & 0x7fff0000) == 0) { + elprintf(EL_SVP, "ssp IRAM copy from %06x", (ssp->mem.bank.RAM1[0]-1)<<1); +#ifdef USE_DEBUGGER + last_iram = (ssp->mem.bank.RAM1[0]-1)<<1; +#endif + } +#endif + return 0; + } + + /* just in case */ + if (ssp->emu_status & SSP_PMC_HAVE_ADDR) { +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: PM%i (%c) with only addr set @ %04x", + reg, write ? 'w' : 'r', GET_PPC_OFFS()); +#endif + ssp->emu_status &= ~SSP_PMC_HAVE_ADDR; + } + + if (reg == 4 || (rST & 0x60)) + { +#ifdef LOG_SVP + #define CADDR ((((mode<<16)&0x7f0000)|addr)<<1) +#endif + unsigned short *dram = (unsigned short *)svp->dram; + if (write) + { + /*int mode = ssp->pmac_write[reg]&0xffff; + int addr = ssp->pmac_write[reg]>>16;*/ + int addr = ssp->pmac[1][reg]&0xffff; + int mode = ssp->pmac[1][reg]>>16; +#ifdef LOG_SVP + if ((mode & 0xb800) == 0xb800) + elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: mode %04x", mode); +#endif + if ((mode & 0x43ff) == 0x0018) /* DRAM */ + { + int inc = get_inc(mode); +#ifdef LOG_SVP + elprintf(EL_SVP, "ssp PM%i DRAM w [%06x] %04x (inc %i, ovrw %i)", + reg, CADDR, d, inc >> 16, (mode>>10)&1); +#endif + if (mode & 0x0400) { + overwite_write(dram[addr], d); + } else dram[addr] = d; + ssp->pmac[1][reg] += inc; + } + else if ((mode & 0xfbff) == 0x4018) /* DRAM, cell inc */ + { +#ifdef LOG_SVP + elprintf(EL_SVP, "ssp PM%i DRAM w [%06x] %04x (cell inc, ovrw %i) @ %04x", + reg, CADDR, d, (mode>>10)&1, GET_PPC_OFFS()); +#endif + if (mode & 0x0400) { + overwite_write(dram[addr], d); + } else dram[addr] = d; + /* ssp->pmac_write[reg] += (addr&1) ? (31<<16) : (1<<16); */ + ssp->pmac[1][reg] += (addr&1) ? 31 : 1; + } + else if ((mode & 0x47ff) == 0x001c) /* IRAM */ + { + int inc = get_inc(mode); +#ifdef LOG_SVP + if ((addr&0xfc00) != 0x8000) + elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: invalid IRAM addr: %04x", addr<<1); + elprintf(EL_SVP, "ssp IRAM w [%06x] %04x (inc %i)", (addr<<1)&0x7ff, d, inc >> 16); +#endif + ((unsigned short *)svp->iram_rom)[addr&0x3ff] = d; + ssp->pmac[1][reg] += inc; + } +#ifdef LOG_SVP + else + { + elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: PM%i unhandled write mode %04x, [%06x] %04x @ %04x", + reg, mode, CADDR, d, GET_PPC_OFFS()); + } +#endif + } + else + { + /*int mode = ssp->pmac_read[reg]&0xffff; + int addr = ssp->pmac_read[reg]>>16;*/ + int addr = ssp->pmac[0][reg]&0xffff; + int mode = ssp->pmac[0][reg]>>16; + + if ((mode & 0xfff0) == 0x0800) /* ROM, inc 1, verified to be correct */ + { +#ifdef LOG_SVP + elprintf(EL_SVP, "ssp ROM r [%06x] %04x", CADDR, + ((unsigned short *)cart.rom)[addr|((mode&0xf)<<16)]); +#endif + /*if ((signed int)ssp->pmac_read[reg] >> 16 == -1) ssp->pmac_read[reg]++; + ssp->pmac_read[reg] += 1<<16;*/ + if ((signed int)(ssp->pmac[0][reg] & 0xffff) == -1) ssp->pmac[0][reg] += 1<<16; + ssp->pmac[0][reg] ++; + + d = ((unsigned short *)cart.rom)[addr|((mode&0xf)<<16)]; + } + else if ((mode & 0x47ff) == 0x0018) /* DRAM */ + { + int inc = get_inc(mode); +#ifdef LOG_SVP + elprintf(EL_SVP, "ssp PM%i DRAM r [%06x] %04x (inc %i)", reg, CADDR, dram[addr], inc >> 16); +#endif + d = dram[addr]; + ssp->pmac[0][reg] += inc; + } + else + { +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: PM%i unhandled read mode %04x, [%06x] @ %04x", + reg, mode, CADDR, GET_PPC_OFFS()); +#endif + d = 0; + } + } + + /* PMC value corresponds to last PMR accessed (not sure). */ + rPMC.v = ssp->pmac[write][reg]; + + return d; + } + + return (u32)-1; +} + +/* 8 */ +static u32 read_PM0(void) +{ + u32 d = pm_io(0, 0, 0); + if (d != (u32)-1) return d; +#ifdef LOG_SVP + elprintf(EL_SVP, "PM0 raw r %04x @ %04x", rPM0, GET_PPC_OFFS()); +#endif + d = rPM0; + if (!(d & 2) && (GET_PPC_OFFS() == 0x800 || GET_PPC_OFFS() == 0x1851E)) { + ssp->emu_status |= SSP_WAIT_PM0; +#ifdef LOG_SVP + elprintf(EL_SVP, "det TIGHT loop: PM0"); +#endif + } + rPM0 &= ~2; /* ? */ + return d; +} + +static void write_PM0(u32 d) +{ + u32 r = pm_io(0, 1, d); + if (r != (u32)-1) return; +#ifdef LOG_SVP + elprintf(EL_SVP, "PM0 raw w %04x @ %04x", d, GET_PPC_OFFS()); +#endif + rPM0 = d; +} + +/* 9 */ +static u32 read_PM1(void) +{ + u32 d = pm_io(1, 0, 0); + if (d != (u32)-1) return d; + /* can be removed? */ +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "PM1 raw r %04x @ %04x", rPM1, GET_PPC_OFFS()); +#endif + return rPM1; +} + +static void write_PM1(u32 d) +{ + u32 r = pm_io(1, 1, d); + if (r != (u32)-1) return; + /* can be removed? */ +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "PM1 raw w %04x @ %04x", d, GET_PPC_OFFS()); +#endif + rPM1 = d; +} + +/* 10 */ +static u32 read_PM2(void) +{ + u32 d = pm_io(2, 0, 0); + if (d != (u32)-1) return d; + /* can be removed? */ +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "PM2 raw r %04x @ %04x", rPM2, GET_PPC_OFFS()); +#endif + return rPM2; +} + +static void write_PM2(u32 d) +{ + u32 r = pm_io(2, 1, d); + if (r != (u32)-1) return; + /* can be removed? */ +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "PM2 raw w %04x @ %04x", d, GET_PPC_OFFS()); +#endif + rPM2 = d; +} + +/* 11 */ +static u32 read_XST(void) +{ + /* can be removed? */ + u32 d = pm_io(3, 0, 0); + if (d != (u32)-1) return d; +#ifdef LOG_SVP + elprintf(EL_SVP, "XST raw r %04x @ %04x", rXST, GET_PPC_OFFS()); +#endif + return rXST; +} + +static void write_XST(u32 d) +{ + /* can be removed? */ + u32 r = pm_io(3, 1, d); + if (r != (u32)-1) return; +#ifdef LOG_SVP + elprintf(EL_SVP, "XST raw w %04x @ %04x", d, GET_PPC_OFFS()); +#endif + rPM0 |= 1; + rXST = d; +} + +/* 12 */ +static u32 read_PM4(void) +{ + u32 d = pm_io(4, 0, 0); + if (d == 0) { + switch (GET_PPC_OFFS()) { + case 0x0854: + ssp->emu_status |= SSP_WAIT_30FE08; +#ifdef LOG_SVP + elprintf(EL_SVP, "det TIGHT loop: [30fe08]"); +#endif + break; + case 0x4f12: + ssp->emu_status |= SSP_WAIT_30FE06; +#ifdef LOG_SVP + elprintf(EL_SVP, "det TIGHT loop: [30fe06]"); +#endif + break; + } + } + if (d != (u32)-1) return d; + /* can be removed? */ +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "PM4 raw r %04x @ %04x", rPM4, GET_PPC_OFFS()); +#endif + return rPM4; +} + +static void write_PM4(u32 d) +{ + u32 r = pm_io(4, 1, d); + if (r != (u32)-1) return; + /* can be removed? */ +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "PM4 raw w %04x @ %04x", d, GET_PPC_OFFS()); +#endif + rPM4 = d; +} + +/* 14 */ +static u32 read_PMC(void) +{ +#ifdef LOG_SVP + elprintf(EL_SVP, "PMC r a %04x (st %c) @ %04x", rPMC.byte.h, + (ssp->emu_status & SSP_PMC_HAVE_ADDR) ? 'm' : 'a', GET_PPC_OFFS()); +#endif + if (ssp->emu_status & SSP_PMC_HAVE_ADDR) { + /* if (ssp->emu_status & SSP_PMC_SET) */ + /* elprintf(EL_ANOMALY|EL_SVP, "prev PMC not used @ %04x", GET_PPC_OFFS()); */ + ssp->emu_status |= SSP_PMC_SET; + ssp->emu_status &= ~SSP_PMC_HAVE_ADDR; + /* return ((rPMC.h << 4) & 0xfff0) | ((rPMC.h >> 4) & 0xf); */ + return ((rPMC.byte.l << 4) & 0xfff0) | ((rPMC.byte.l >> 4) & 0xf); + } else { + ssp->emu_status |= SSP_PMC_HAVE_ADDR; + /* return rPMC.h; */ + return rPMC.byte.l; + } +} + +static void write_PMC(u32 d) +{ + if (ssp->emu_status & SSP_PMC_HAVE_ADDR) { + /* if (ssp->emu_status & SSP_PMC_SET) */ + /* elprintf(EL_ANOMALY|EL_SVP, "prev PMC not used @ %04x", GET_PPC_OFFS()); */ + ssp->emu_status |= SSP_PMC_SET; + ssp->emu_status &= ~SSP_PMC_HAVE_ADDR; + /* rPMC.l = d; */ + rPMC.byte.h = d; +#ifdef LOG_SVP + elprintf(EL_SVP, "PMC w m %04x @ %04x", rPMC.byte.l, GET_PPC_OFFS()); +#endif + } else { + ssp->emu_status |= SSP_PMC_HAVE_ADDR; + /* rPMC.h = d; */ + rPMC.byte.l = d; +#ifdef LOG_SVP + elprintf(EL_SVP, "PMC w a %04x @ %04x", rPMC.byte.h, GET_PPC_OFFS()); +#endif + } +} + +/* 15 */ +static u32 read_AL(void) +{ + if (*(PC-1) == 0x000f) { +#ifdef LOG_SVP + elprintf(EL_SVP, "ssp dummy PM assign %08x @ %04x", rPMC.v, GET_PPC_OFFS()); +#endif + ssp->emu_status &= ~(SSP_PMC_SET|SSP_PMC_HAVE_ADDR); /* ? */ + } + return rAL; +} + +static void write_AL(u32 d) +{ + rAL = d; +} + + +typedef u32 (*read_func_t)(void); +typedef void (*write_func_t)(u32 d); + +static read_func_t read_handlers[16] = +{ + read_unknown, read_unknown, read_unknown, read_unknown, /* -, X, Y, A */ + read_unknown, /* 4 ST */ + read_STACK, + read_PC, + read_P, + read_PM0, /* 8 */ + read_PM1, + read_PM2, + read_XST, + read_PM4, /* 12 */ + read_unknown, /* 13 gr13 */ + read_PMC, + read_AL +}; + +static write_func_t write_handlers[16] = +{ + write_unknown, write_unknown, write_unknown, write_unknown, /* -, X, Y, A */ +/* write_unknown, */ /* 4 ST */ + write_ST, /* 4 ST (debug hook) */ + write_STACK, + write_PC, + write_unknown, /* 7 P */ + write_PM0, /* 8 */ + write_PM1, + write_PM2, + write_XST, + write_PM4, /* 12 */ + write_unknown, /* 13 gr13 */ + write_PMC, + write_AL +}; + +/* ----------------------------------------------------- */ +/* pointer register handlers */ + +#define ptr1_read(op) ptr1_read_(op&3,(op>>6)&4,(op<<1)&0x18) + +static u32 ptr1_read_(int ri, int isj2, int modi3) +{ + /* int t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18); */ + u32 mask, add = 0, t = ri | isj2 | modi3; + unsigned char *rp = NULL; + switch (t) + { + /* mod=0 (00) */ + case 0x00: + case 0x01: + case 0x02: return ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]]; + case 0x03: return ssp->mem.bank.RAM0[0]; + case 0x04: + case 0x05: + case 0x06: return ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]]; + case 0x07: return ssp->mem.bank.RAM1[0]; + /* mod=1 (01), "+!" */ + case 0x08: + case 0x09: + case 0x0a: return ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]++]; + case 0x0b: return ssp->mem.bank.RAM0[1]; + case 0x0c: + case 0x0d: + case 0x0e: return ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]++]; + case 0x0f: return ssp->mem.bank.RAM1[1]; + /* mod=2 (10), "-" */ + case 0x10: + case 0x11: + case 0x12: rp = &ssp->ptr.bank.r0[t&3]; t = ssp->mem.bank.RAM0[*rp]; + if (!(rST&7)) { (*rp)--; return t; } + add = -1; goto modulo; + case 0x13: return ssp->mem.bank.RAM0[2]; + case 0x14: + case 0x15: + case 0x16: rp = &ssp->ptr.bank.r1[t&3]; t = ssp->mem.bank.RAM1[*rp]; + if (!(rST&7)) { (*rp)--; return t; } + add = -1; goto modulo; + case 0x17: return ssp->mem.bank.RAM1[2]; + /* mod=3 (11), "+" */ + case 0x18: + case 0x19: + case 0x1a: rp = &ssp->ptr.bank.r0[t&3]; t = ssp->mem.bank.RAM0[*rp]; + if (!(rST&7)) { (*rp)++; return t; } + add = 1; goto modulo; + case 0x1b: return ssp->mem.bank.RAM0[3]; + case 0x1c: + case 0x1d: + case 0x1e: rp = &ssp->ptr.bank.r1[t&3]; t = ssp->mem.bank.RAM1[*rp]; + if (!(rST&7)) { (*rp)++; return t; } + add = 1; goto modulo; + case 0x1f: return ssp->mem.bank.RAM1[3]; + } + + return 0; + +modulo: + mask = (1 << (rST&7)) - 1; + *rp = (*rp & ~mask) | ((*rp + add) & mask); + return t; +} + +static void ptr1_write(int op, u32 d) +{ + int t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18); + switch (t) + { + /* mod=0 (00) */ + case 0x00: + case 0x01: + case 0x02: ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]] = d; return; + case 0x03: ssp->mem.bank.RAM0[0] = d; return; + case 0x04: + case 0x05: + case 0x06: ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]] = d; return; + case 0x07: ssp->mem.bank.RAM1[0] = d; return; + /* mod=1 (01), "+!" */ + /* mod=3, "+" */ + case 0x08: + case 0x18: + case 0x09: + case 0x19: + case 0x0a: + case 0x1a: ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]++] = d; return; + case 0x0b: ssp->mem.bank.RAM0[1] = d; return; + case 0x0c: + case 0x1c: + case 0x0d: + case 0x1d: + case 0x0e: + case 0x1e: ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]++] = d; return; + case 0x0f: ssp->mem.bank.RAM1[1] = d; return; + /* mod=2 (10), "-" */ + case 0x10: + case 0x11: + case 0x12: ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]--] = d; return; + case 0x13: ssp->mem.bank.RAM0[2] = d; return; + case 0x14: + case 0x15: + case 0x16: ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]--] = d; return; + case 0x17: ssp->mem.bank.RAM1[2] = d; return; + /* mod=3 (11) */ + case 0x1b: ssp->mem.bank.RAM0[3] = d; return; + case 0x1f: ssp->mem.bank.RAM1[3] = d; return; + } +} + +static u32 ptr2_read(int op) +{ + int mv = 0, t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18); + switch (t) + { + /* mod=0 (00) */ + case 0x00: + case 0x01: + case 0x02: mv = ssp->mem.bank.RAM0[ssp->ptr.bank.r0[t&3]]++; break; + case 0x03: mv = ssp->mem.bank.RAM0[0]++; break; + case 0x04: + case 0x05: + case 0x06: mv = ssp->mem.bank.RAM1[ssp->ptr.bank.r1[t&3]]++; break; + case 0x07: mv = ssp->mem.bank.RAM1[0]++; break; + /* mod=1 (01) */ + case 0x0b: mv = ssp->mem.bank.RAM0[1]++; break; + case 0x0f: mv = ssp->mem.bank.RAM1[1]++; break; + /* mod=2 (10) */ + case 0x13: mv = ssp->mem.bank.RAM0[2]++; break; + case 0x17: mv = ssp->mem.bank.RAM1[2]++; break; + /* mod=3 (11) */ + case 0x1b: mv = ssp->mem.bank.RAM0[3]++; break; + case 0x1f: mv = ssp->mem.bank.RAM1[3]++; break; + default: +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: invalid mod in ((rX))? @ %04x", GET_PPC_OFFS()); +#endif + return 0; + } + + return ((unsigned short *)svp->iram_rom)[mv]; +} + + +/* ----------------------------------------------------- */ + +void ssp1601_reset(ssp1601_t *l_ssp) +{ + ssp = l_ssp; + ssp->emu_status = 0; + ssp->gr[SSP_GR0].v = 0xffff0000; + rPC = 0x400; + rSTACK = 0; /* ? using ascending stack */ + rST = 0; +} + + +#ifdef USE_DEBUGGER +static void debug_dump(void) +{ + printf("GR0: %04x X: %04x Y: %04x A: %08x\n", ssp->gr[SSP_GR0].byte.h, rX, rY, ssp->gr[SSP_A].v); + printf("PC: %04x (%04x) P: %08x\n", GET_PC(), GET_PC() << 1, ssp->gr[SSP_P].v); + printf("PM0: %04x PM1: %04x PM2: %04x\n", rPM0, rPM1, rPM2); + printf("XST: %04x PM4: %04x PMC: %08x\n", rXST, rPM4, ssp->gr[SSP_PMC].v); + printf(" ST: %04x %c%c%c%c, GP0_0 %i, GP0_1 %i\n", rST, rST&SSP_FLAG_N?'N':'n', rST&SSP_FLAG_V?'V':'v', + rST&SSP_FLAG_Z?'Z':'z', rST&SSP_FLAG_L?'L':'l', (rST>>5)&1, (rST>>6)&1); + printf("STACK: %i %04x %04x %04x %04x %04x %04x\n", rSTACK, ssp->stack[0], ssp->stack[1], + ssp->stack[2], ssp->stack[3], ssp->stack[4], ssp->stack[5]); + printf("r0-r2: %02x %02x %02x r4-r6: %02x %02x %02x\n", rIJ[0], rIJ[1], rIJ[2], rIJ[4], rIJ[5], rIJ[6]); + elprintf(EL_SVP, "cycles: %i, emu_status: %x", g_cycles, ssp->emu_status); +} + +static void debug_dump_mem(void) +{ + int h, i; + printf("RAM0\n"); + for (h = 0; h < 32; h++) + { + if (h == 16) printf("RAM1\n"); + printf("%03x:", h*16); + for (i = 0; i < 16; i++) + printf(" %04x", ssp->mem.RAM[h*16+i]); + printf("\n"); + } +} + +static void debug_dump2file(const char *fname, void *mem, int len) +{ + FILE *f = fopen(fname, "wb"); + unsigned short *p = mem; + int i; + if (f) { + for (i = 0; i < len/2; i++) p[i] = (p[i]<<8) | (p[i]>>8); + fwrite(mem, 1, len, f); + fclose(f); + for (i = 0; i < len/2; i++) p[i] = (p[i]<<8) | (p[i]>>8); + printf("dumped to %s\n", fname); + } + else + printf("dump failed\n"); +} + +static int bpts[10] = { 0, }; + +static void debug(unsigned int pc, unsigned int op) +{ + static char buffo[64] = {0,}; + char buff[64] = {0,}; + int i; + + if (running) { + for (i = 0; i < 10; i++) + if (pc != 0 && bpts[i] == pc) { + printf("breakpoint %i\n", i); + running = 0; + break; + } + } + if (running) return; + + printf("%04x (%02x) @ %04x\n", op, op >> 9, pc<<1); + + while (1) + { + printf("dbg> "); + fflush(stdout); + fgets(buff, sizeof(buff), stdin); + if (buff[0] == '\n') strcpy(buff, buffo); + else strcpy(buffo, buff); + + switch (buff[0]) { + case 0: exit(0); + case 'c': + case 'r': running = 1; return; + case 's': + case 'n': return; + case 'x': debug_dump(); break; + case 'm': debug_dump_mem(); break; + case 'b': { + char *baddr = buff + 2; + i = 0; + if (buff[3] == ' ') { i = buff[2] - '0'; baddr = buff + 4; } + bpts[i] = strtol(baddr, NULL, 16) >> 1; + printf("breakpoint %i set @ %04x\n", i, bpts[i]<<1); + break; + } + case 'd': + sprintf(buff, "iramrom_%04x.bin", last_iram); + debug_dump2file(buff, svp->iram_rom, sizeof(svp->iram_rom)); + debug_dump2file("dram.bin", svp->dram, sizeof(svp->dram)); + break; + default: printf("unknown command\n"); break; + } + } +} +#endif /* USE_DEBUGGER */ + + +void ssp1601_run(int cycles) +{ + SET_PC(rPC); + g_cycles = cycles; + + do + { + int op; + u32 tmpv; + + op = *PC++; +#ifdef USE_DEBUGGER + debug(GET_PC()-1, op); +#endif + switch (op >> 9) + { + /* ld d, s */ + case 0x00: + if (op == 0) break; /* nop */ + if (op == ((SSP_A<<4)|SSP_P)) { /* A <- P */ + /* not sure. MAME claims that only hi word is transfered. */ + read_P(); /* update P */ + rA32 = rP.v; + } + else + { + tmpv = REG_READ(op & 0x0f); + REG_WRITE((op & 0xf0) >> 4, tmpv); + } + break; + + /* ld d, (ri) */ + case 0x01: tmpv = ptr1_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv); break; + + /* ld (ri), s */ + case 0x02: tmpv = REG_READ((op & 0xf0) >> 4); ptr1_write(op, tmpv); break; + + /* ldi d, imm */ + case 0x04: tmpv = *PC++; REG_WRITE((op & 0xf0) >> 4, tmpv); break; + + /* ld d, ((ri)) */ + case 0x05: tmpv = ptr2_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv); break; + + /* ldi (ri), imm */ + case 0x06: tmpv = *PC++; ptr1_write(op, tmpv); break; + + /* ld adr, a */ + case 0x07: ssp->mem.RAM[op & 0x1ff] = rA; break; + + /* ld d, ri */ + case 0x09: tmpv = rIJ[(op&3)|((op>>6)&4)]; REG_WRITE((op & 0xf0) >> 4, tmpv); break; + + /* ld ri, s */ + case 0x0a: rIJ[(op&3)|((op>>6)&4)] = REG_READ((op & 0xf0) >> 4); break; + + /* ldi ri, simm */ + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: rIJ[(op>>8)&7] = op; break; + + /* call cond, addr */ + case 0x24: { + int cond = 0; + COND_CHECK + if (cond) { int new_PC = *PC++; write_STACK(GET_PC()); write_PC(new_PC); } + else PC++; + break; + } + + /* ld d, (a) */ + case 0x25: tmpv = ((unsigned short *)svp->iram_rom)[rA]; REG_WRITE((op & 0xf0) >> 4, tmpv); break; + + /* bra cond, addr */ + case 0x26: { + int cond = 0; + COND_CHECK + if (cond) { int new_PC = *PC++; write_PC(new_PC); } + else PC++; + break; + } + + /* mod cond, op */ + case 0x48: { + int cond = 0; + COND_CHECK + if (cond) { + switch (op & 7) { + case 2: rA32 = (signed int)rA32 >> 1; break; /* shr (arithmetic) */ + case 3: rA32 <<= 1; break; /* shl */ + case 6: rA32 = -(signed int)rA32; break; /* neg */ + case 7: if ((int)rA32 < 0) rA32 = -(signed int)rA32; break; /* abs */ + default: +#ifdef LOG_SVP + elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: unhandled mod %i @ %04x", + op&7, GET_PPC_OFFS()); +#endif + break; + } + UPD_ACC_ZN /* ? */ + } + break; + } + + /* mpys? */ + case 0x1b: +#ifdef LOG_SVP + if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS()); +#endif + read_P(); /* update P */ + rA32 -= rP.v; /* maybe only upper word? */ + UPD_ACC_ZN /* there checking flags after this */ + rX = ptr1_read_(op&3, 0, (op<<1)&0x18); /* ri (maybe rj?) */ + rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); /* rj */ + break; + + /* mpya (rj), (ri), b */ + case 0x4b: +#ifdef LOG_SVP + if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS()); +#endif + read_P(); /* update P */ + rA32 += rP.v; /* confirmed to be 32bit */ + UPD_ACC_ZN /* ? */ + rX = ptr1_read_(op&3, 0, (op<<1)&0x18); /* ri (maybe rj?) */ + rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); /* rj */ + break; + + /* mld (rj), (ri), b */ + case 0x5b: +#ifdef LOG_SVP + if (!(op&0x100)) elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: no b bit @ %04x", GET_PPC_OFFS()); +#endif + rA32 = 0; + rST &= 0x0fff; /* ? */ + rX = ptr1_read_(op&3, 0, (op<<1)&0x18); /* ri (maybe rj?) */ + rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); /* rj */ + break; + + /* OP a, s */ + case 0x10: OP_CHECK32(OP_SUBA32); tmpv = REG_READ(op & 0x0f); OP_SUBA(tmpv); break; + case 0x30: OP_CHECK32(OP_CMPA32); tmpv = REG_READ(op & 0x0f); OP_CMPA(tmpv); break; + case 0x40: OP_CHECK32(OP_ADDA32); tmpv = REG_READ(op & 0x0f); OP_ADDA(tmpv); break; + case 0x50: OP_CHECK32(OP_ANDA32); tmpv = REG_READ(op & 0x0f); OP_ANDA(tmpv); break; + case 0x60: OP_CHECK32(OP_ORA32 ); tmpv = REG_READ(op & 0x0f); OP_ORA (tmpv); break; + case 0x70: OP_CHECK32(OP_EORA32); tmpv = REG_READ(op & 0x0f); OP_EORA(tmpv); break; + + /* OP a, (ri) */ + case 0x11: tmpv = ptr1_read(op); OP_SUBA(tmpv); break; + case 0x31: tmpv = ptr1_read(op); OP_CMPA(tmpv); break; + case 0x41: tmpv = ptr1_read(op); OP_ADDA(tmpv); break; + case 0x51: tmpv = ptr1_read(op); OP_ANDA(tmpv); break; + case 0x61: tmpv = ptr1_read(op); OP_ORA (tmpv); break; + case 0x71: tmpv = ptr1_read(op); OP_EORA(tmpv); break; + + /* OP a, adr */ + case 0x03: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_LDA (tmpv); break; + case 0x13: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_SUBA(tmpv); break; + case 0x33: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_CMPA(tmpv); break; + case 0x43: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_ADDA(tmpv); break; + case 0x53: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_ANDA(tmpv); break; + case 0x63: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_ORA (tmpv); break; + case 0x73: tmpv = ssp->mem.RAM[op & 0x1ff]; OP_EORA(tmpv); break; + + /* OP a, imm */ + case 0x14: tmpv = *PC++; OP_SUBA(tmpv); break; + case 0x34: tmpv = *PC++; OP_CMPA(tmpv); break; + case 0x44: tmpv = *PC++; OP_ADDA(tmpv); break; + case 0x54: tmpv = *PC++; OP_ANDA(tmpv); break; + case 0x64: tmpv = *PC++; OP_ORA (tmpv); break; + case 0x74: tmpv = *PC++; OP_EORA(tmpv); break; + + /* OP a, ((ri)) */ + case 0x15: tmpv = ptr2_read(op); OP_SUBA(tmpv); break; + case 0x35: tmpv = ptr2_read(op); OP_CMPA(tmpv); break; + case 0x45: tmpv = ptr2_read(op); OP_ADDA(tmpv); break; + case 0x55: tmpv = ptr2_read(op); OP_ANDA(tmpv); break; + case 0x65: tmpv = ptr2_read(op); OP_ORA (tmpv); break; + case 0x75: tmpv = ptr2_read(op); OP_EORA(tmpv); break; + + /* OP a, ri */ + case 0x19: tmpv = rIJ[IJind]; OP_SUBA(tmpv); break; + case 0x39: tmpv = rIJ[IJind]; OP_CMPA(tmpv); break; + case 0x49: tmpv = rIJ[IJind]; OP_ADDA(tmpv); break; + case 0x59: tmpv = rIJ[IJind]; OP_ANDA(tmpv); break; + case 0x69: tmpv = rIJ[IJind]; OP_ORA (tmpv); break; + case 0x79: tmpv = rIJ[IJind]; OP_EORA(tmpv); break; + + /* OP simm */ + case 0x1c: + OP_SUBA(op & 0xff); +#ifdef LOG_SVP + if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); +#endif + break; + case 0x3c: + OP_CMPA(op & 0xff); +#ifdef LOG_SVP + if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); +#endif + break; + case 0x4c: + OP_ADDA(op & 0xff); +#ifdef LOG_SVP + if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); +#endif + break; + /* MAME code only does LSB of top word, but this looks wrong to me. */ + case 0x5c: + OP_ANDA(op & 0xff); +#ifdef LOG_SVP + if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); +#endif + break; + case 0x6c: + OP_ORA (op & 0xff); +#ifdef LOG_SVP + if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); +#endif + break; + case 0x7c: + OP_EORA(op & 0xff); +#ifdef LOG_SVP + if (op&0x100) elprintf(EL_SVP|EL_ANOMALY, "FIXME: simm with upper bit set"); +#endif + break; + + default: +#ifdef LOG_SVP + elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME unhandled op %04x @ %04x", op, GET_PPC_OFFS()); +#endif + break; + } + } + while (--g_cycles > 0 && !(ssp->emu_status & SSP_WAIT_MASK)); + + read_P(); /* update P */ + rPC = GET_PC(); + +#ifdef LOG_SVP + if (ssp->gr[SSP_GR0].v != 0xffff0000) + elprintf(EL_ANOMALY|EL_SVP, "ssp FIXME: REG 0 corruption! %08x", ssp->gr[SSP_GR0].v); +#endif +} + diff --git a/genplus-gx/core/cart_hw/svp/ssp16.h b/genplus-gx/core/cart_hw/svp/ssp16.h new file mode 100644 index 0000000000..1717489df3 --- /dev/null +++ b/genplus-gx/core/cart_hw/svp/ssp16.h @@ -0,0 +1,79 @@ +/* + basic, incomplete SSP160x (SSP1601?) interpreter + with SVP memory controller emu + + (c) Copyright 2008, Grazvydas "notaz" Ignotas + Free for non-commercial use. + + For commercial use, separate licencing terms must be obtained. + + Modified for Genesis Plus GX (Eke-Eke): added BIG ENDIAN support, fixed addr/code inversion +*/ + +#ifndef _SSP16_H_ +#define _SSP16_H_ + +/* emulation event logging (from Picodrive) */ +#ifdef LOG_SVP +#define EL_SVP 0x00004000 /* SVP stuff */ +#define EL_ANOMALY 0x80000000 /* some unexpected conditions (during emulation) */ +#define elprintf(w,f,...) error("%d(%d): " f "\n",frame_count,v_counter,##__VA_ARGS__); +#endif + +/* register names */ +enum { + SSP_GR0, SSP_X, SSP_Y, SSP_A, + SSP_ST, SSP_STACK, SSP_PC, SSP_P, + SSP_PM0, SSP_PM1, SSP_PM2, SSP_XST, + SSP_PM4, SSP_gr13, SSP_PMC, SSP_AL +}; + +typedef union +{ + unsigned int v; + struct { +#ifdef LSB_FIRST + unsigned short l; + unsigned short h; +#else + unsigned short h; + unsigned short l; +#endif + } byte; +} ssp_reg_t; + +typedef struct +{ + union { + unsigned short RAM[256*2]; /* 2 internal RAM banks */ + struct { + unsigned short RAM0[256]; + unsigned short RAM1[256]; + } bank; + } mem; + ssp_reg_t gr[16]; /* general registers */ + union { + unsigned char r[8]; /* BANK pointers */ + struct { + unsigned char r0[4]; + unsigned char r1[4]; + } bank; + } ptr; + unsigned short stack[6]; + unsigned int pmac[2][6]; /* read/write modes/addrs for PM0-PM5 */ + #define SSP_PMC_HAVE_ADDR 0x0001 /* address written to PMAC, waiting for mode */ + #define SSP_PMC_SET 0x0002 /* PMAC is set */ + #define SSP_HANG 0x1000 /* 68000 hangs SVP */ + #define SSP_WAIT_PM0 0x2000 /* bit1 in PM0 */ + #define SSP_WAIT_30FE06 0x4000 /* ssp tight loops on 30FE08 to become non-zero */ + #define SSP_WAIT_30FE08 0x8000 /* same for 30FE06 */ + #define SSP_WAIT_MASK 0xf000 + unsigned int emu_status; + unsigned int pad[30]; +} ssp1601_t; + + +void ssp1601_reset(ssp1601_t *ssp); +void ssp1601_run(int cycles); + +#endif diff --git a/genplus-gx/core/cart_hw/svp/svp.c b/genplus-gx/core/cart_hw/svp/svp.c new file mode 100644 index 0000000000..9176319fd5 --- /dev/null +++ b/genplus-gx/core/cart_hw/svp/svp.c @@ -0,0 +1,49 @@ +/* + basic, incomplete SSP160x (SSP1601?) interpreter + with SVP memory controller emu + + (c) Copyright 2008, Grazvydas "notaz" Ignotas + Free for non-commercial use. + + For commercial use, separate licencing terms must be obtained. + + Modified for Genesis Plus GX (Eke-Eke): added BIG ENDIAN support, fixed addr/code inversion +*/ + +#include "shared.h" + +svp_t *svp = NULL; + +void svp_init(void) +{ + svp = (void *) ((char *)cart.rom + 0x200000); + memset(svp, 0, sizeof(*svp)); +} + +void svp_reset(void) +{ + memcpy(svp->iram_rom + 0x800, cart.rom + 0x800, 0x20000 - 0x800); + ssp1601_reset(&svp->ssp1601); +} + +void svp_write_dram(uint32 address, uint32 data) +{ + *(uint16 *)(svp->dram + (address & 0x1fffe)) = data; + if ((address == 0x30fe06) && data) svp->ssp1601.emu_status &= ~SSP_WAIT_30FE06; + if ((address == 0x30fe08) && data) svp->ssp1601.emu_status &= ~SSP_WAIT_30FE08; +} + +uint32 svp_read_cell_1(uint32 address) +{ + address >>= 1; + address = (address & 0x7001) | ((address & 0x3e) << 6) | ((address & 0xfc0) >> 5); + return *(uint16 *)(svp->dram + (address & 0x1fffe)); +} + +uint32 svp_read_cell_2(uint32 address) +{ + address >>= 1; + address = (address & 0x7801) | ((address & 0x1e) << 6) | ((address & 0x7e0) >> 4); + return *(uint16 *)(svp->dram + (address & 0x1fffe)); +} + diff --git a/genplus-gx/core/cart_hw/svp/svp.h b/genplus-gx/core/cart_hw/svp/svp.h new file mode 100644 index 0000000000..e052053465 --- /dev/null +++ b/genplus-gx/core/cart_hw/svp/svp.h @@ -0,0 +1,33 @@ +/* + basic, incomplete SSP160x (SSP1601?) interpreter + with SVP memory controller emu + + (c) Copyright 2008, Grazvydas "notaz" Ignotas + Free for non-commercial use. + + For commercial use, separate licencing terms must be obtained. + + Modified for Genesis Plus GX (Eke-Eke): added BIG ENDIAN support, fixed addr/code inversion +*/ + +#ifndef _SVP_H_ +#define _SVP_H_ + +#include "shared.h" +#include "ssp16.h" + +typedef struct { + unsigned char iram_rom[0x20000]; /* IRAM (0-0x7ff) and program ROM (0x800-0x1ffff) */ + unsigned char dram[0x20000]; + ssp1601_t ssp1601; +} svp_t; + +extern svp_t *svp; + +extern void svp_init(void); +extern void svp_reset(void); +extern void svp_write_dram(uint32 address, uint32 data); +extern uint32 svp_read_cell_1(uint32 address); +extern uint32 svp_read_cell_2(uint32 address); + +#endif diff --git a/genplus-gx/core/cart_hw/svp/svpdoc.txt b/genplus-gx/core/cart_hw/svp/svpdoc.txt new file mode 100644 index 0000000000..001178cd3d --- /dev/null +++ b/genplus-gx/core/cart_hw/svp/svpdoc.txt @@ -0,0 +1,524 @@ +------------------------------------------------------------------------------- + notaz's SVP doc + $Id: svpdoc.txt 349 2008-02-04 23:13:59Z notaz $ + Copyright 2008, Grazvydas Ignotas (notaz) +------------------------------------------------------------------------------- + +If you use this, please credit me in your work or it's documentation. +Tasco Deluxe should also be credited for his pioneering work on the subject. +Thanks. + +Use monospace font and disable word wrap when reading this document. + +------------------------------------------------------------------------------- + Table of Contents +------------------------------------------------------------------------------- + + 0. Introduction + 1. Overview + 2. The SSP160x DSP + 2.1. General registers + 2.2. External registers + 2.3. Pointer registers + 2.4. The instruction set + 3. Memory map + 4. Other notes + + +------------------------------------------------------------------------------- + 0. Introduction +------------------------------------------------------------------------------- + +This document is an attempt to provide technical information needed to +emulate Sega's SVP chip. It is based on reverse engineering Virtua Racing +game and on various internet sources. None of information provided here +was verified on the real hardware, so some things are likely to be +inaccurate. + +The following information sources were used while writing this document +and emulator implementation: + + [1] SVP Reference Guide (annotated) and SVP Register Guide (annotated) + by Tasco Deluxe < tasco.deluxe @ gmail.com > + http://www.sharemation.com/TascoDLX/SVP%20Reference%20Guide%202007.02.11.txt + http://www.sharemation.com/TascoDLX/SVP%20Register%20Guide%202007.02.11.txt + [2] SSP1610 disassembler + written by Pierpaolo Prazzoli, MAME source code. + http://mamedev.org/ + [3] SSP1601 DSP datasheet + http://notaz.gp2x.de/docs/SSP1601.pdf + [4] DSP page (with code samples) in Samsung Semiconductor website from 1997 + retrieved from Internet Archive: The Wayback Machine + http://web.archive.org/web/19970607052826/www.sec.samsung.com/Products/dsp/dspcore.htm + [5] Sega's SVP Chip: The Road not Taken? + Ken Horowitz, Sega-16 + http://sega-16.com/feature_page.php?id=37&title=Sega's%20SVP%20Chip:%20The%20Road%20not%20Taken? + + +------------------------------------------------------------------------------- + 1. Overview +------------------------------------------------------------------------------- + +The only game released with SVP chip was Virtua Racing. There are at least 4 +versions of the game: USA, Jap and 2 different Eur revisions. Three of them +share identical SSP160x code, one of the Eur revisions has some differences. + +From the software developer's point of view, the game cartridge contains +at least: + + * Samsung SSP160x 16-bit DSP core, which includes [3]: + * Two independent high-speed RAM banks, accessed in single clock cycle, + 256 words each. + * 16 x 16 bit multiply unit. + * 32-bit ALU, status register. + * Hardware stack of 6 levels. + * 128KB of DRAM. + * 2KB of IRAM (instruction RAM). + * Memory controller with address mapping capability. + * 2MB of game ROM. + +[5] claims there is also "2 Channels PWM" in the cartridge, but it's either +not used or not there at all. +Various sources claim that SSP160x is SSP1601 which is likely to be true, +because the code doesn't seem to use any SSP1605+ features. + + +------------------------------------------------------------------------------- + 2. The SSP160x DSP +------------------------------------------------------------------------------- + +SSP160x is 16-bit DSP, capable of performing multiplication + addition in +single clock cycle [3]. It has 8 general, 8 external and 8 pointer registers. +There is a status register which has operation control bits and condition +flags. Condition flags are set/cleared during ALU (arithmetic, logic) +operations. It also has 6-level hardware stack and 2 internal RAM banks +RAM0 and RAM1, 256 words each. + +The device is only capable of addressing 16-bit words, so all addresses refer +to words (16bit value in ROM, accessed by 68k through address 0x84 would be +accessed by SSP160x using address 0x42). + +[3] mentions interrupt pins, but interrupts don't seem to be used by SVP code +(actually there are functions which look like interrupt handler routines, but +they don't seem to do anything important). + +2.1. General registers +---------------------- + +There are 8 general registers: -, X, Y, A, ST, STACK, PC and P ([2] [4]). +Size is given in bits. + +2.1.1. "-" + Constant register with all bits set (0xffff). Also used for programming + external registers (blind reads/writes, see 2.2). + size: 16 + +2.1.2. "X" + Generic register. Also acts as a multiplier 1 for P register. + size: 16 + +2.1.3. "Y" + Generic register. Also acts as a multiplier 2 for P register. + size: 16 + +2.1.4. "A" + Accumulator. Stores the result of all ALU (but not multiply) operations, + status register is updated according to this. When directly accessed, + only upper word is read/written. Low word can be accessed by using AL + (see 2.2.8). + size: 32 + +2.1.5. "ST" + STatus register. Bits 0-9 are CONTROL, other are FLAG [2]. Only some of + them are actually used by SVP. + Bits: fedc ba98 7654 3210 + 210 - RPL "Loop size". If non-zero, makes (rX+) and (rX-) respectively + modulo-increment and modulo-decrement (see 2.3). The value + shows which power of 2 to use, i.e. 4 means modulo by 16. + 43 - RB Unknown. Not used by SVP code. + 5 - ST5 Affects behavior of external registers. See 2.2. + 6 - ST6 Affects behavior of external registers. See 2.2. + According to [3] (5,6) bits correspond to hardware pins. + 7 - IE Interrupt enable? Not used by SVP code. + 8 - OP Saturated value? Not used by SVP code. + 9 - MACS MAC shift? Not used by SVP code. + a - GPI_0 Interrupt 0 enable/status? Not used by SVP code. + b - GPI_1 Interrupt 1 enable/status? Not used by SVP code. + c - L L flag. Similar to carry? Not used by SVP code. + d - Z Zero flag. Set after ALU operations, when all 32 accumulator + bits become zero. + e - OV Overflow flag. Not used by SVP code. + f - N Negative flag. Set after ALU operations, when bit31 in + accumulator is 1. + size: 16 + +2.1.6. "STACK" + Hardware stack of 6 levels [3]. Values are "pushed" by directly writing to + it, or by "call" instruction. "Pop" is performed by directly reading the + register or by "ret" instruction. + size: 16 + +2.1.7. "PC" + Program Counter. Can be written directly to perform a jump. It is not clear + if it is possible to read it (SVP code never does). + size: 16 + +2.1.8. "P" + multiply Product - multiplication result register. + Always contains 32-bit multiplication result of X, Y and 2 (P = X * Y * 2). + X and Y are sign-extended before performing the multiplication. + size: 32 + +2.2. External registers +----------------------- + +The external registers, as the name says, are external to SSP160x, they are +hooked to memory controller in SVP, so by accessing them we actually program +the memory controller. They act as programmable memory access registers or +external status registers [1]. Some of them can act as both, depending on how +ST5 ans ST6 bits are set in status register. After a register is programmed, +accessing it causes reads/writes from/to external memory (see section 3 for +the memory map). The access may also cause some additional effects, like +incremental of address, associated with accessed register. +In this document and my emu, instead of using names EXT0-EXT7 +from [4] I used different names for these registers. Those names are from +Tasco Deluxe's [1] doc. + +All these registers can be blind-accessed (as said in [1]) by performing +(ld -, PMx) or (ld PMx, -). This programs them to access memory (except PMC, +where the effect is different). +All registers are 16-bit. + +2.2.1. "PM0" + If ST5 or ST6 is set, acts as Programmable Memory access register + (see 2.2.7). Else it acts as status of XST (2.2.4). It is also mapped + to a15004 on 68k side: + ???????? ??????10 + 0: set, when SSP160x has written something to XST + (cleared when 015004 is read by 68k) + 1: set, when 68k has written something to a15000 or a15002 + (cleared on PM0 read by SSP160x) + Note that this is likely to be incorrect, but such behavior is OK for + emulation to work. + +2.2.2. "PM1" + Programmable Memory access register. Only accessed with ST bits set by + SVP code. + +2.2.3. "PM2" + Same as PM1. + +2.2.4. "XST" + If ST5 or ST6 is set, acts as Programmable Memory access register + (only used by memory test code). Else it acts as eXternal STatus + register, which is also mapped to a15000 and a15002 on 68k side. + Affects PM0 when written to. + +2.2.5. "PM4" + Programmable Memory access register. Not affected by ST5 and ST6 bits, + always stays in PMAR mode. + +2.2.6. "EXT5" + Not used by SVP, so not covered by this document. + +2.2.7. "PMC" + Programmable Memory access Control. It is set using 2 16bit writes, first + address, then mode word. After setting PMAC, PMx should be blind accessed + using (ld -, PMx) or (ld PMx, -) to program it for reading or writing + external memory respectively. Every PMx register can be programmed to + access it's own memory location with it's own mode. Registers are programmed + separately for reading and writing. + + Reading PMC register also shifts it's state (from "waiting for address" to + "waiting for mode" and back). Reads always return address word related to + last PMx register accessed, or last address word written to PMC (whichever + event happened last before PMC read). + + The address word contains bits 0-15 of the memory word-address. + The mode word format is as follows: + dsnnnv?? ???aaaaa + a: bits 16-20 of memory word-address. + n: auto-increment value. If set, after every access of PMx, word-address + value related to it will be incremented by (words): + 1 - 1 5 - 16 + 2 - 2 6 - 32 + 3 - 4 7 - 128 + 4 - 8 + d: make auto-increment negative - decrement by count listed above. + s: special-increment mode. If current address is even (when accessing + programmed PMx), increment it by 1. Else, increment by 32. It is not + clear what happens if d and n bits are also set (never done by SVP). + v: over-write mode when writing, unknown when reading (not used). + Over-write mode splits the word being written into 4 half-bytes and + only writes those half-bytes, which are not zero. + When auto-increment is performed, it affects all 21 address bits. + +2.2.8. "AL" + This register acts more like a general register. + If this register is blind-accessed, it is "dummy programmed", i.e. nothing + happens and PMC is reset to "waiting for address" state. + In all other cases, it is Accumulator Low, 16 least significant bits of + accumulator. Normally reading acc (ld X, A) you get 16 most significant + bits, so this allows you access the low word of 32bit accumulator. + +2.3. Pointer registers +---------------------- + +There are 8 8-bit pointer registers rX, which are internal to SSP160x and are +used to access internal RAM banks RAM0 and RAM1, or program memory indirectly. +r0-r3 (ri) point to RAM0, r4-r7 (rj) point to RAM1. Each bank has 256 words of +RAM, so 8bit registers can fully address them. The registers can be accessed +directly, or 2 indirection levels can be used [ (rX), ((rX)) ]. They work +similar to * and ** operators in C, only they use different types of memory +and ((rX)) also performs post-increment. First indirection level (rX) accesses +a word in RAMx, second accesses program memory at address read from (rX), and +increments value in (rX). + +Only r0,r1,r2,r4,r5,r6 can be directly modified (ldi r0, 5), or by using +modifiers. 3 modifiers can be applied when using first indirection level +(optional): + + : post-increment (ld a, (r0+) ). Increment register value after operation. + Can be made modulo-increment by setting RPL bits in status register + (see 2.1.5). + - : post-decrement. Also can be made modulo-decrement by using RPL bits in ST. + +!: post-increment, unaffected by RPL (probably). +These are only used on 1st indirection level, so things like ( ld a, ((r0+)) ) +and (ld X, r6-) are probably invalid. + +r3 and r7 are special and can not be changed (at least Samsung samples [4] and +SVP code never do). They are fixed to the start of their RAM banks. (They are +probably changeable for ssp1605+, Samsung's old DSP page claims that). +1 of these 4 modifiers must be used on these registers (short form direct +addressing? [2]): + |00: RAMx[0] The very first word in the RAM bank. + |01: RAMx[1] Second word + |10: RAMx[2] ... + |11: RAMx[3] + +2.4. The instruction set +------------------------ + +The Samsung SSP16 series assembler uses right-to-left notation ([2] [4]): +ld X, Y +means value from Y should be copied to X. + +Size of every instruction is word, some have extension words for immediate +values. When writing an interpreter, 7 most significant bits are usually +enough to determine which opcode it is. + +encoding bits are marked as: +rrrr - general or external register, in order specified in 2.1 and 2.2 + (0 is '-', 1 'X', ..., 8 is 'PM0', ..., 0xf is 'AL') +dddd - same as above, as destination operand +ssss - same as above, as source operand +jpp - pointer register index, 0-7 +j - specifies RAM bank, i.e. RAM0 or RAM1 +i* - immediate value bits +a* - offset in internal RAM bank +mm - modifier for pointer register, depending on register: + r0-r2,r4-r6 r3,r7 examples + 0: (none) |00 ld a, (r0) cmp a, (r7|00) + 1: +! |01 ld (r0+!), a ld (r7|01), a + 2: - |10 add a, (r0-) + 3: + |11 +cccc - encodes condition, only 3 used by SVP, see check_cond() below +ooo - operation to perform + +Operation is written in C-style pseudo-code, where: +program_memory[X] - access program memory at address X +RAMj[X] - access internal RAM bank j=0,1 (RAM0 or RAM1), word + offset X +RIJ[X] - pointer register rX, X=0-7 +pr_modif_read(m,X) - read pointer register rX, applying modifier m: + if register is r3 or r7, return value m + else switch on value m: + 0: return rX; + 1: tmp = rX; rX++; return tmp; // rX+! + 2: tmp = rX; modulo_decrement(rX); return tmp; // rX- + 3: tmp = rX; modulo_increment(rX); return tmp; // rX+ + the modulo value used (if used at all) depends on ST + RPL bits (see 2.1.5) +check_cond(c,f) - checks if a flag matches f bit: + switch (c) { + case 0: return true; + case 5: return (Z == f) ? true : false; // check Z flag + case 7: return (N == f) ? true : false; // check N flag + } // other conditions are possible, but they are not used +update_flags() - update ST flags according to last ALU operation. +sign_extend(X) - sign extend 16bit value X to 32bits. +next_op_address() - address of instruction after current instruction. + +2.4.1. ALU instructions + +All of these instructions update flags, which are set according to full 32bit +accumulator. The SVP code only checks N and Z flags, so it is not known when +exactly OV and L flags are set. Operations are performed on full A, so +(andi A, 0) would clear all 32 bits of A. + +They share the same addressing modes. The exact arithmetic operation is +determined by 3 most significant (ooo) bits: + 001 - sub - subtract (OP -=) + 011 - cmp - compare (OP -, flags are updated according to result) + 100 - add - add (OP +=) + 101 - and - binary AND (OP &=) + 110 - or - binary OR (OP |=) + 111 - eor - exclusive OR (OP ^=) + + syntax encoding operation + OP A, s ooo0 0000 0000 rrrr A OP r << 16; + OP A, (ri) ooo0 001j 0000 mmpp A OP RAMj[pr_modif_read(m,jpp)] << 16; + OP A, adr ooo0 011j aaaa aaaa A OP RAMj[a] << 16; + OPi A, imm ooo0 1000 0000 0000 A OP i << 16; + iiii iiii iiii iiii + op A, ((ri)) ooo0 101j 0000 mmpp tmp = pr_modif_read(m,jpp); + A OP program_memory[RAMj[tmp]] << 16; + RAMj[tmp]++; + op A, ri ooo1 001j 0000 00pp A OP RIJ[jpp] << 16; + OPi simm ooo1 1000 iiii iiii A OP i << 16; + +There is also "perform operation on accumulator" instruction: + + syntax encoding operation + mod cond, op 1001 000f cccc 0ooo if (check_cond(c,f)) switch(o) { + case 2: A >>= 1; break; // arithmetic shift + case 3: A <<= 1; break; + case 6: A = -A; break; // negate A + case 7: A = abs(A); break; // absolute val. + } // other operations are possible, but + // they are not used by SVP. + +2.4.2. Load (move) instructions + +These instructions never affect flags (even ld A). +If destination is A, and source is 16bit, only upper word is transfered (same +thing happens on opposite). If dest. is A, and source is P, whole 32bit value +is transfered. It is not clear if P can be destination operand (probably not, +no code ever does this). +Writing to STACK pushes a value there, reading pops. It is not known what +happens on overflow/underflow (never happens in SVP code). +ld -, - is used as a nop. + + syntax encoding operation + ld d, s 0000 0000 dddd ssss d = s; + ld d, (ri) 0000 001j dddd mmpp d = RAMj[pr_modif_read(m,jpp)]; + ld (ri), s 0000 010j ssss mmpp RAMj[pr_modif_read(m,jpp)] = s; + ldi d, imm 0000 1000 dddd 0000 d = i; + iiii iiii iiii iiii + ld d, ((ri)) 0000 101j dddd mmpp tmp = pr_modif_read(m,jpp); + d = program_memory[RAMj[tmp]]; + RAMj[tmp]++; + ldi (ri), imm 0000 110l 0000 mmpp RAMj[pr_modif_read(m,jpp)] = i; + iiii iiii iiii iiii + ld adr, a 0000 111j aaaa aaaa RAMj[a] = A; + ld d, ri 0001 001j dddd 00pp d = RIJ[jpp]; + ld ri, s 0001 010j ssss 00pp RIJ[jpp] = s; + ldi ri, simm 0001 1jpp iiii iiii RIJ[jpp] = i; + ld d, (a) 0100 1010 dddd 0000 d = program_memory[A[31:16]]; + // read a word from program memory. Offset + // is the upper word in A. + +2.4.3. Program control instructions + +Only 3 instructions: call, ret (alias of ld PC, STACK) and branch. Indirect +jumps can be performed by simply writing to PC. + + syntax encoding operation + call cond, addr 0100 100f cccc 0000 if (check_cond(c,f)) { + aaaa aaaa aaaa aaaa STACK = next_op_address(); PC = a; + } + bra cond, addr 0100 110f cccc 0000 if (check_cond(c,f)) PC = a; + aaaa aaaa aaaa aaaa + ret 0000 0000 0110 0101 PC = STACK; // same as ld PC, STACK + +2.4.4. Multiply-accumulate instructions + +Not sure if (ri) and (rj) really get loaded into X and Y, but multiplication +result surely is loaded into P. There is probably optional 3rd operand (1, 0; +encoded by bit16, default 1), but it's not used by SVP code. + + syntax encoding operation + mld (rj), (ri) 1011 0111 nnjj mmii A = 0; update_flags(); + X = RAM0[pr_modif_read(m,0ii)]; + Y = RAM1[pr_modif_read(m,1jj)]; + P = sign_extend(X) * sign_extend(Y) * 2 + mpya (rj), (ri) 1001 0111 nnjj mmii A += P; update_flags(); + X = RAM0[pr_modif_read(m,0ii)]; + Y = RAM1[pr_modif_read(m,1jj)]; + P = sign_extend(X) * sign_extend(Y) * 2 + mpys (rj), (ri) 0011 0111 nnjj mmii A -= P; update_flags(); + X = RAM0[pr_modif_read(m,0ii)]; + Y = RAM1[pr_modif_read(m,1jj)]; + P = sign_extend(X) * sign_extend(Y) * 2 + +------------------------------------------------------------------------------- + 3. Memory map +------------------------------------------------------------------------------- + +The SSp160x can access it's own program memory, and external memory through EXT +registers (see 2.2). Program memory is read-execute-only, the size of this +space is 64K words (this is how much 16bit PC can address): + + byte address word address name + 0- 7ff 0- 3ff IRAM + 800-1ffff 400-ffff ROM + +There were reports that SVP has internal ROM, but fortunately they were wrong. +The location 800-1ffff is mapped from the same location in the 2MB game ROM. +The IRAM is read-only (as SSP160x doesn't have any means of writing to it's +program memory), but it can be changed through external memory space, as it's +also mapped there. + +The external memory space seems to match the one visible by 68k, with some +differences: + + 68k space SVP space word address name + 0-1fffff 0-1fffff 0- fffff game ROM + 300000-31ffff 300000-31ffff 180000-18ffff DRAM + ? 390000-3907ff 1c8000-1c83ff IRAM + 390000-39ffff ? ? "cell arrange" 1 + 3a0000-3affff ? ? "cell arrange" 2 + a15000-a15009 n/a n/a Status/control registers + +The external memory can be read/written by SSP160x (except game ROM, which can +only be read). + +"cell arrange" 1 and 2 are similar to the one used in SegaCD, they map +300000-30ffff location to 390000-39ffff and 3a0000-3affff, where linear image +written to 300000 can be read as VDP patterns at 390000. Virtua Racing doesn't +seem to use this feature, it is only used by memory test code. + +Here is the list of status/control registers (16bit size): + a15000 - w/r command/result register. Visible as XST for SSP160x (2.2.4). + a15002 - mirror of the above. + a15004 - status of command/result register (see 2.2.1). + a15006 - possibly halts the SVP. Before doing DMA from DRAM, 68k code writes + 0xa, and after it's finished, writes 0. This is probably done to + prevent SVP accessing DRAM and avoid bus clashes. + a15008 - possibly causes an interrupt. There is (unused?) code which writes + 0, 1, and again 0 in sequence. + + +------------------------------------------------------------------------------- + 4. Other notes +------------------------------------------------------------------------------- + +The game has arcade-style memory self-check mode, which can be accessed by +pressing _all_ buttons (including directions) on 3-button controller. There was +probably some loopback plug for this. + +SVP seems to have DMA latency issue similar to one in Sega CD, as the code +always sets DMA source address value larger by 2, then intended for copy. +This is even true for DMAs from ROM, as it's probably hooked through SVP's +memory controller. + +The entry point for the code seems to be at address 0x800 (word 0x400) in ROM, +but it is not clear where the address is fetched from when the system powers +up. The memory test code also sets up "ld PC, .." opcodes at 0x7f4, 0x7f8 and +0x7fc, which jump to some routines, possibly interrupt handlers. This means +that mentioned addresses might be built-in interrupt vectors. + +The SVP code doesn't seem to be timing sensitive, so it can be emulated without +knowing timing of the instructions or even how fast the chip is clocked. +Overclocking doesn't have any effect, underclocking causes slowdowns. Running +10-12M instructions/sec (or possibly less) is sufficient. + diff --git a/genplus-gx/core/cd_hw/cd_cart.c b/genplus-gx/core/cd_hw/cd_cart.c new file mode 100644 index 0000000000..954222162b --- /dev/null +++ b/genplus-gx/core/cd_hw/cd_cart.c @@ -0,0 +1,267 @@ +/*************************************************************************************** + * Genesis Plus + * CD compatible ROM/RAM cartridge support + * + * Copyright (C) 2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + + +/*--------------------------------------------------------------------------*/ +/* backup RAM cartridge (max. 512KB) */ +/*--------------------------------------------------------------------------*/ +static unsigned int cart_ram_read_byte(unsigned int address) +{ + /* LSB only */ + if (address & 1) + { + return scd.cartridge.area[(address >> 1) & scd.cartridge.mask]; + } + + return 0xff; +} + +static unsigned int cart_ram_read_word(unsigned int address) +{ + return (scd.cartridge.area[(address >> 1) & scd.cartridge.mask] | 0xff00); +} + +static void cart_ram_write_byte(unsigned int address, unsigned int data) +{ + /* LSB only */ + if (address & 1) + { + scd.cartridge.area[(address >> 1) & scd.cartridge.mask] = data; + } +} + +static void cart_ram_write_word(unsigned int address, unsigned int data) +{ + scd.cartridge.area[(address >> 1) & scd.cartridge.mask] = data & 0xff; +} + + +/*--------------------------------------------------------------------------*/ +/* backup RAM cartridge ID */ +/*--------------------------------------------------------------------------*/ + +static unsigned int cart_id_read_byte(unsigned int address) +{ + /* LSB only */ + if (address & 1) + { + return scd.cartridge.id; + } + + return 0xff; +} + +static unsigned int cart_id_read_word(unsigned int address) +{ + return (scd.cartridge.id | 0xff00); +} + + +/*--------------------------------------------------------------------------*/ +/* backup RAM cartridge write protection */ +/*--------------------------------------------------------------------------*/ + +static unsigned int cart_prot_read_byte(unsigned int address) +{ + /* LSB only */ + if (address & 1) + { + return scd.cartridge.prot; + } + + return 0xff; +} + +static unsigned int cart_prot_read_word(unsigned int address) +{ + return (scd.cartridge.prot | 0xff00); +} + +static void cart_prot_write_byte(unsigned int address, unsigned int data) +{ + /* LSB only */ + if (address & 1) + { + int i; + + if (data & 1) + { + /* cartridge is write enabled */ + for (i=0x60; i<0x70; i++) + { + m68k.memory_map[i].write8 = cart_ram_write_byte; + m68k.memory_map[i].write16 = cart_ram_write_word; + zbank_memory_map[i].write = cart_ram_write_byte; + } + } + else + { + /* cartridge is write protected */ + for (i=0x60; i<0x70; i++) + { + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].write = zbank_unused_w; + } + } + + scd.cartridge.prot = data; + } +} + +static void cart_prot_write_word(unsigned int address, unsigned int data) +{ + int i; + + if (data & 1) + { + /* cartridge is write enabled */ + for (i=0x60; i<0x70; i++) + { + m68k.memory_map[i].write8 = cart_ram_write_byte; + m68k.memory_map[i].write16 = cart_ram_write_word; + zbank_memory_map[i].write = cart_ram_write_byte; + } + } + else + { + /* cartridge is write protected */ + for (i=0x60; i<0x70; i++) + { + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].write = zbank_unused_w; + } + } + + scd.cartridge.prot = data & 0xff; +} + +/*--------------------------------------------------------------------------*/ +/* ROM/RAM cartridge initialization */ +/*--------------------------------------------------------------------------*/ +void cd_cart_init(void) +{ + int i; + + /* System boot mode */ + if (scd.cartridge.boot) + { + /* disable backup RAM cartridge when booting from cartridge (Mode 1) */ + scd.cartridge.id = 0; + } + else + { + /* enable 512K backup RAM cartridge when booting from CD (Mode 2) */ + scd.cartridge.id = 6; + } + + /* RAM cartridge enabled ? */ + if (scd.cartridge.id) + { + /* disable cartridge backup memory */ + memset(&sram, 0, sizeof (T_SRAM)); + + /* clear backup RAM */ + memset(scd.cartridge.area, 0x00, sizeof(scd.cartridge.area)); + + /* backup RAM size mask */ + scd.cartridge.mask = (1 << (scd.cartridge.id + 13)) - 1; + + /* enable RAM cartridge write access */ + scd.cartridge.prot = 1; + + /* RAM cartridge ID register (read-only) */ + for (i=0x40; i<0x60; i++) + { + m68k.memory_map[i].base = NULL; + m68k.memory_map[i].read8 = cart_id_read_byte; + m68k.memory_map[i].read16 = cart_id_read_word; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].read = cart_id_read_byte; + zbank_memory_map[i].write = zbank_unused_w; + } + + /* RAM cartridge memory */ + for (i=0x60; i<0x70; i++) + { + m68k.memory_map[i].base = NULL; + m68k.memory_map[i].read8 = cart_ram_read_byte; + m68k.memory_map[i].read16 = cart_ram_read_word; + m68k.memory_map[i].write8 = cart_ram_write_byte; + m68k.memory_map[i].write16 = cart_ram_write_word; + zbank_memory_map[i].read = cart_ram_read_byte; + zbank_memory_map[i].write = cart_ram_write_byte; + } + + /* RAM cartridge write protection register */ + for (i=0x70; i<0x80; i++) + { + m68k.memory_map[i].base = NULL; + m68k.memory_map[i].read8 = cart_prot_read_byte; + m68k.memory_map[i].read16 = cart_prot_read_word; + m68k.memory_map[i].write8 = cart_prot_write_byte; + m68k.memory_map[i].write16 = cart_prot_write_word; + zbank_memory_map[i].read = cart_prot_read_byte; + zbank_memory_map[i].write = cart_prot_write_byte; + } + } + else + { + /* initialize ROM cartridge */ + md_cart_init(); + + /* when booting from CD, cartridge is mapped to $400000-$7FFFFF */ + if (!scd.cartridge.boot) + { + for (i=0; i<0x40; i++) + { + m68k.memory_map[i+0x40].base = m68k.memory_map[i].base; + m68k.memory_map[i+0x40].read8 = m68k.memory_map[i].read8; + m68k.memory_map[i+0x40].read16 = m68k.memory_map[i].read16; + m68k.memory_map[i+0x40].write8 = m68k.memory_map[i].write8; + m68k.memory_map[i+0x40].write16 = m68k.memory_map[i].write16; + zbank_memory_map[i+0x40].read = zbank_memory_map[i].read; + zbank_memory_map[i+0x40].write = zbank_memory_map[i].write; + } + } + } +} diff --git a/genplus-gx/core/cd_hw/cd_cart.h b/genplus-gx/core/cd_hw/cd_cart.h new file mode 100644 index 0000000000..7fef4bd778 --- /dev/null +++ b/genplus-gx/core/cd_hw/cd_cart.h @@ -0,0 +1,51 @@ +/*************************************************************************************** + * Genesis Plus + * CD compatible ROM/RAM cartridge support + * + * Copyright (C) 2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + + + /* CD compatible ROM/RAM cartridge */ +typedef struct +{ + uint8 area[0x810000]; /* cartridge ROM/RAM area (max. 8MB + 64KB backup) */ + uint8 boot; /* cartridge boot mode (0x00: boot from CD with ROM/RAM cartridge enabled, 0x40: boot from ROM cartridge with CD enabled) */ + uint8 id; /* RAM cartridge ID (related to RAM size, 0 if disabled) */ + uint8 prot; /* RAM cartridge write protection */ + uint32 mask; /* RAM cartridge size mask */ +} cd_cart_t; + +/* Function prototypes */ +extern void cd_cart_init(void); diff --git a/genplus-gx/core/cd_hw/cdc.c b/genplus-gx/core/cd_hw/cdc.c new file mode 100644 index 0000000000..25a15c3efd --- /dev/null +++ b/genplus-gx/core/cd_hw/cdc.c @@ -0,0 +1,705 @@ +/*************************************************************************************** + * Genesis Plus + * CD data controller (LC89510 compatible) + * + * Copyright (C) 2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +/* IFSTAT register bitmasks */ +#define BIT_DTEI 0x40 +#define BIT_DECI 0x20 +#define BIT_DTBSY 0x08 +#define BIT_DTEN 0x02 + +/* IFCTRL register bitmasks */ +#define BIT_DTEIEN 0x40 +#define BIT_DECIEN 0x20 +#define BIT_DOUTEN 0x02 + +/* CTRL0 register bitmasks */ +#define BIT_DECEN 0x80 +#define BIT_E01RQ 0x20 +#define BIT_AUTORQ 0x10 +#define BIT_WRRQ 0x04 + +/* CTRL1 register bitmasks */ +#define BIT_MODRQ 0x08 +#define BIT_FORMRQ 0x04 +#define BIT_SHDREN 0x01 + +/* CTRL2 register bitmask */ +#define BIT_VALST 0x80 + +/* TODO: figure exact DMA transfer rate */ +#define DMA_BYTES_PER_LINE 512 + +void cdc_init(void) +{ + memset(&cdc, 0, sizeof(cdc_t)); +} + +void cdc_reset(void) +{ + /* reset CDC register index */ + scd.regs[0x04>>1].byte.l = 0x00; + + /* reset CDC registers */ + cdc.ifstat = 0xff; + cdc.ifctrl = 0x00; + cdc.ctrl[0] = 0x00; + cdc.ctrl[1] = 0x00; + cdc.stat[0] = 0x00; + cdc.stat[1] = 0x00; + cdc.stat[2] = 0x00; + cdc.stat[3] = 0x80; + cdc.head[0][0] = 0x00; + cdc.head[0][1] = 0x00; + cdc.head[0][2] = 0x00; + cdc.head[0][3] = 0x01; + cdc.head[1][0] = 0x00; + cdc.head[1][1] = 0x00; + cdc.head[1][2] = 0x00; + cdc.head[1][3] = 0x00; + + /* reset CDC cycle counter */ + cdc.cycles = 0; + + /* DMA transfer disabled */ + cdc.dma_w = 0; + + /* clear any pending IRQ */ + if (scd.pending & (1 << 5)) + { + /* clear any pending interrupt level 5 */ + scd.pending &= ~(1 << 5); + + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } +} + +int cdc_context_save(uint8 *state) +{ + uint8 tmp8; + int bufferptr = 0; + + if (cdc.dma_w == pcm_ram_dma_w) + { + tmp8 = 1; + } + else if (cdc.dma_w == prg_ram_dma_w) + { + tmp8 = 2; + } + else if (cdc.dma_w == word_ram_0_dma_w) + { + tmp8 = 3; + } + else if (cdc.dma_w == word_ram_1_dma_w) + { + tmp8 = 4; + } + else if (cdc.dma_w == word_ram_2M_dma_w) + { + tmp8 = 5; + } + else + { + tmp8 = 0; + } + + save_param(&cdc, sizeof(cdc)); + save_param(&tmp8, 1); + + return bufferptr; +} + +int cdc_context_load(uint8 *state) +{ + uint8 tmp8; + int bufferptr = 0; + + load_param(&cdc, sizeof(cdc)); + load_param(&tmp8, 1); + + switch (tmp8) + { + case 1: + cdc.dma_w = pcm_ram_dma_w; + break; + case 2: + cdc.dma_w = prg_ram_dma_w; + break; + case 3: + cdc.dma_w = word_ram_0_dma_w; + break; + case 4: + cdc.dma_w = word_ram_1_dma_w; + break; + case 5: + cdc.dma_w = word_ram_2M_dma_w; + break; + default: + cdc.dma_w = 0; + break; + } + + return bufferptr; +} + +void cdc_dma_update(void) +{ + /* maximal transfer length */ + int length = DMA_BYTES_PER_LINE; + + /* end of DMA transfer ? */ + if (cdc.dbc.w < DMA_BYTES_PER_LINE) + { + /* transfer remaining words using 16-bit DMA */ + cdc.dma_w((cdc.dbc.w + 1) >> 1); + + /* reset data byte counter (DBCH bits 4-7 should be set to 1) */ + cdc.dbc.w = 0xf000; + + /* clear !DTEN and !DTBSY */ + cdc.ifstat |= (BIT_DTBSY | BIT_DTEN); + + /* pending Data Transfer End interrupt */ + cdc.ifstat &= ~BIT_DTEI; + + /* Data Transfer End interrupt enabled ? */ + if (cdc.ifctrl & BIT_DTEIEN) + { + /* pending level 5 interrupt */ + scd.pending |= (1 << 5); + + /* level 5 interrupt enabled ? */ + if (scd.regs[0x32>>1].byte.l & 0x20) + { + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + + /* clear DSR bit & set EDT bit (CD register $04) */ + scd.regs[0x04>>1].byte.h = (scd.regs[0x04>>1].byte.h & 0x07) | 0x80; + + /* SUB-CPU idle on register $04 polling ? */ + if (s68k.stopped & (1<<0x04)) + { + /* sync SUB-CPU with CDC */ + s68k.cycles = scd.cycles; + + /* restart SUB-CPU */ + s68k.stopped = 0; +#ifdef LOG_SCD + error("s68k started from %d cycles\n", s68k.cycles); +#endif + } + + /* disable DMA transfer */ + cdc.dma_w = 0; + } + else + { + /* transfer all words using 16-bit DMA */ + cdc.dma_w(DMA_BYTES_PER_LINE >> 1); + + /* decrement data byte counter */ + cdc.dbc.w -= length; + } +} + +int cdc_decoder_update(uint32 header) +{ + /* data decoding enabled ? */ + if (cdc.ctrl[0] & BIT_DECEN) + { + /* update HEAD registers */ + *(uint32 *)(cdc.head[0]) = header; + + /* set !VALST */ + cdc.stat[3] = 0x00; + + /* pending decoder interrupt */ + cdc.ifstat &= ~BIT_DECI; + + /* decoder interrupt enabled ? */ + if (cdc.ifctrl & BIT_DECIEN) + { + /* pending level 5 interrupt */ + scd.pending |= (1 << 5); + + /* level 5 interrupt enabled ? */ + if (scd.regs[0x32>>1].byte.l & 0x20) + { + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + + /* buffer RAM write enabled ? */ + if (cdc.ctrl[0] & BIT_WRRQ) + { + uint16 offset; + + /* increment block pointer */ + cdc.pt.w += 2352; + + /* increment write address */ + cdc.wa.w += 2352; + + /* CDC buffer address */ + offset = cdc.pt.w & 0x3fff; + + /* write CDD block header (4 bytes) */ + *(uint32 *)(cdc.ram + offset) = header; + + /* write CDD block data (2048 bytes) */ + cdd_read_data(cdc.ram + 4 + offset); + + /* take care of buffer overrun */ + if (offset > (0x4000 - 2048 - 4)) + { + /* data should be written at the start of buffer */ + memcpy(cdc.ram, cdc.ram + 0x4000, offset + 2048 + 4 - 0x4000); + } + + /* read next data block */ + return 1; + } + } + + /* keep decoding same data block if Buffer Write is disabled */ + return 0; +} + +void cdc_reg_w(unsigned char data) +{ +#ifdef LOG_CDC + error("CDC register %X write 0x%04x (%X)\n", scd.regs[0x04>>1].byte.l & 0x0F, data, s68k.pc); +#endif + switch (scd.regs[0x04>>1].byte.l & 0x0F) + { + case 0x01: /* IFCTRL */ + { + /* pending interrupts ? */ + if (((data & BIT_DTEIEN) && !(cdc.ifstat & BIT_DTEI)) || + ((data & BIT_DECIEN) && !(cdc.ifstat & BIT_DECI))) + { + /* pending level 5 interrupt */ + scd.pending |= (1 << 5); + + /* level 5 interrupt enabled ? */ + if (scd.regs[0x32>>1].byte.l & 0x20) + { + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + else if (scd.pending & (1 << 5)) + { + /* clear pending level 5 interrupts */ + scd.pending &= ~(1 << 5); + + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + + /* abort any data transfer if data output is disabled */ + if (!(data & BIT_DOUTEN)) + { + /* clear !DTBSY and !DTEN */ + cdc.ifstat |= (BIT_DTBSY | BIT_DTEN); + } + + cdc.ifctrl = data; + scd.regs[0x04>>1].byte.l = 0x02; + break; + } + + case 0x02: /* DBCL */ + cdc.dbc.byte.l = data; + scd.regs[0x04>>1].byte.l = 0x03; + break; + + case 0x03: /* DBCH */ + cdc.dbc.byte.h = data; + scd.regs[0x04>>1].byte.l = 0x04; + break; + + case 0x04: /* DACL */ + cdc.dac.byte.l = data; + scd.regs[0x04>>1].byte.l = 0x05; + break; + + case 0x05: /* DACH */ + cdc.dac.byte.h = data; + scd.regs[0x04>>1].byte.l = 0x06; + break; + + case 0x06: /* DTRG */ + { + /* start data transfer if data output is enabled */ + if (cdc.ifctrl & BIT_DOUTEN) + { + /* set !DTBSY */ + cdc.ifstat &= ~BIT_DTBSY; + + /* clear DBCH bits 4-7 */ + cdc.dbc.byte.h &= 0x0f; + + /* clear EDT & DSR bits (SCD register $04) */ + scd.regs[0x04>>1].byte.h &= 0x07; + + /* setup data transfer destination */ + switch (scd.regs[0x04>>1].byte.h & 0x07) + { + case 2: /* MAIN-CPU host read */ + case 3: /* SUB-CPU host read */ + { + /* set !DTEN */ + cdc.ifstat &= ~BIT_DTEN; + + /* set DSR bit (register $04) */ + scd.regs[0x04>>1].byte.h |= 0x40; + break; + } + + case 4: /* PCM RAM DMA */ + { + cdc.dma_w = pcm_ram_dma_w; + break; + } + + case 5: /* PRG-RAM DMA */ + { + cdc.dma_w = prg_ram_dma_w; + break; + } + + case 7: /* WORD-RAM DMA */ + { + /* check memory mode */ + if (scd.regs[0x02 >> 1].byte.l & 0x04) + { + /* 1M mode */ + if (scd.regs[0x02 >> 1].byte.l & 0x01) + { + /* Word-RAM bank 0 is assigned to SUB-CPU */ + cdc.dma_w = word_ram_0_dma_w; + } + else + { + /* Word-RAM bank 1 is assigned to SUB-CPU */ + cdc.dma_w = word_ram_1_dma_w; + } + } + else + { + /* 2M mode */ + if (scd.regs[0x02 >> 1].byte.l & 0x02) + { + /* only process DMA if Word-RAM is assigned to SUB-CPU */ + cdc.dma_w = word_ram_2M_dma_w; + } + } + break; + } + + default: /* invalid */ + { + #ifdef LOG_CDC + error("invalid CDC tranfer destination (%d)\n", scd.regs[0x04>>1].byte.h & 0x07); + #endif + break; + } + } + } + + scd.regs[0x04>>1].byte.l = 0x07; + break; + } + + case 0x07: /* DTACK */ + { + /* clear pending data transfer end interrupt */ + cdc.ifstat |= BIT_DTEI; + + /* clear DBCH bits 4-7 */ + cdc.dbc.byte.h &= 0x0f; + +#if 0 + /* no pending decoder interrupt ? */ + if ((cdc.ifstat | BIT_DECI) || !(cdc.ifctrl & BIT_DECIEN)) + { + /* clear pending level 5 interrupt */ + scd.pending &= ~(1 << 5); + + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } +#endif + scd.regs[0x04>>1].byte.l = 0x08; + break; + } + + case 0x08: /* WAL */ + cdc.wa.byte.l = data; + scd.regs[0x04>>1].byte.l = 0x09; + break; + + case 0x09: /* WAH */ + cdc.wa.byte.h = data; + scd.regs[0x04>>1].byte.l = 0x0a; + break; + + case 0x0a: /* CTRL0 */ + { + /* set CRCOK bit only if decoding is enabled */ + cdc.stat[0] = data & BIT_DECEN; + + /* update decoding mode */ + if (data & BIT_AUTORQ) + { + /* set MODE bit according to CTRL1 register & clear FORM bit */ + cdc.stat[2] = cdc.ctrl[1] & BIT_MODRQ; + } + else + { + /* set MODE & FORM bits according to CTRL1 register */ + cdc.stat[2] = cdc.ctrl[1] & (BIT_MODRQ | BIT_FORMRQ); + } + + cdc.ctrl[0] = data; + scd.regs[0x04>>1].byte.l = 0x0b; + break; + } + + case 0x0b: /* CTRL1 */ + { + /* update decoding mode */ + if (cdc.ctrl[0] & BIT_AUTORQ) + { + /* set MODE bit according to CTRL1 register & clear FORM bit */ + cdc.stat[2] = data & BIT_MODRQ; + } + else + { + /* set MODE & FORM bits according to CTRL1 register */ + cdc.stat[2] = data & (BIT_MODRQ | BIT_FORMRQ); + } + + cdc.ctrl[1] = data; + scd.regs[0x04>>1].byte.l = 0x0c; + break; + } + + case 0x0c: /* PTL */ + cdc.pt.byte.l = data; + scd.regs[0x04>>1].byte.l = 0x0d; + break; + + case 0x0d: /* PTH */ + cdc.pt.byte.h = data; + scd.regs[0x04>>1].byte.l = 0x0e; + break; + + case 0x0e: /* CTRL2 (unused) */ + scd.regs[0x04>>1].byte.l = 0x0f; + break; + + case 0x0f: /* RESET */ + cdc_reset(); + break; + + default: /* by default, SBOUT is not used */ + break; + } +} + +unsigned char cdc_reg_r(void) +{ + switch (scd.regs[0x04>>1].byte.l & 0x0F) + { + case 0x01: /* IFSTAT */ + scd.regs[0x04>>1].byte.l = 0x02; + return cdc.ifstat; + + case 0x02: /* DBCL */ + scd.regs[0x04>>1].byte.l = 0x03; + return cdc.dbc.byte.l; + + case 0x03: /* DBCH */ + scd.regs[0x04>>1].byte.l = 0x04; + return cdc.dbc.byte.h; + + case 0x04: /* HEAD0 */ + scd.regs[0x04>>1].byte.l = 0x05; + return cdc.head[cdc.ctrl[1] & BIT_SHDREN][0]; + + case 0x05: /* HEAD1 */ + scd.regs[0x04>>1].byte.l = 0x06; + return cdc.head[cdc.ctrl[1] & BIT_SHDREN][1]; + + case 0x06: /* HEAD2 */ + scd.regs[0x04>>1].byte.l = 0x07; + return cdc.head[cdc.ctrl[1] & BIT_SHDREN][2]; + + case 0x07: /* HEAD3 */ + scd.regs[0x04>>1].byte.l = 0x08; + return cdc.head[cdc.ctrl[1] & BIT_SHDREN][3]; + + case 0x08: /* PTL */ + scd.regs[0x04>>1].byte.l = 0x09; + return cdc.pt.byte.l; + + case 0x09: /* PTH */ + scd.regs[0x04>>1].byte.l = 0x0a; + return cdc.pt.byte.h; + + case 0x0a: /* WAL */ + scd.regs[0x04>>1].byte.l = 0x0b; + return cdc.wa.byte.l; + + case 0x0b: /* WAH */ + scd.regs[0x04>>1].byte.l = 0x0c; + return cdc.wa.byte.h; + + case 0x0c: /* STAT0 */ + scd.regs[0x04>>1].byte.l = 0x0d; + return cdc.stat[0]; + + case 0x0d: /* STAT1 (always return 0) */ + scd.regs[0x04>>1].byte.l = 0x0e; + return 0x00; + + case 0x0e: /* STAT2 */ + scd.regs[0x04>>1].byte.l = 0x0f; + return cdc.stat[2]; + + case 0x0f: /* STAT3 */ + { + uint8 data = cdc.stat[3]; + + /* clear !VALST (note: this is not 100% correct but BIOS do not seem to care) */ + cdc.stat[3] = BIT_VALST; + + /* clear pending decoder interrupt */ + cdc.ifstat |= BIT_DECI; + +#if 0 + /* no pending data transfer end interrupt */ + if ((cdc.ifstat | BIT_DTEI) || !(cdc.ifctrl & BIT_DTEIEN)) + { + /* clear pending level 5 interrupt */ + scd.pending &= ~(1 << 5); + + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } +#endif + + scd.regs[0x04>>1].byte.l = 0x00; + return data; + } + + default: /* by default, COMIN is always empty */ + return 0xff; + } +} + +unsigned short cdc_host_r(void) +{ + /* check if data is available */ + if (!(cdc.ifstat & BIT_DTEN)) + { + /* read data word from CDC RAM buffer */ + uint16 data = *(uint16 *)(cdc.ram + (cdc.dac.w & 0x3ffe)); + +#ifdef LSB_FIRST + /* source data is stored in big endian format */ + data = ((data >> 8) | (data << 8)) & 0xffff; +#endif + +#ifdef LOG_CDC + error("CDC host read 0x%04x -> 0x%04x (dbc=0x%x) (%X)\n", cdc.dac.w, data, cdc.dbc.w, s68k.pc); +#endif + + /* increment data address counter */ + cdc.dac.w += 2; + + /* decrement data byte counter */ + cdc.dbc.w -= 2; + + /* end of transfer ? */ + if ((int16)cdc.dbc.w <= 0) + { + /* reset data byte counter (DBCH bits 4-7 should be set to 1) */ + cdc.dbc.w = 0xf000; + + /* clear !DTEN and !DTBSY */ + cdc.ifstat |= (BIT_DTBSY | BIT_DTEN); + + /* pending Data Transfer End interrupt */ + cdc.ifstat &= ~BIT_DTEI; + + /* Data Transfer End interrupt enabled ? */ + if (cdc.ifctrl & BIT_DTEIEN) + { + /* pending level 5 interrupt */ + scd.pending |= (1 << 5); + + /* level 5 interrupt enabled ? */ + if (scd.regs[0x32>>1].byte.l & 0x20) + { + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + + /* clear DSR bit & set EDT bit (SCD register $04) */ + scd.regs[0x04>>1].byte.h = (scd.regs[0x04>>1].byte.h & 0x07) | 0x80; + } + + return data; + } + +#ifdef LOG_CDC + error("error reading CDC host (data transfer disabled)\n"); +#endif + return 0xffff; +} diff --git a/genplus-gx/core/cd_hw/cdc.h b/genplus-gx/core/cd_hw/cdc.h new file mode 100644 index 0000000000..01267f9283 --- /dev/null +++ b/genplus-gx/core/cd_hw/cdc.h @@ -0,0 +1,71 @@ +/*************************************************************************************** + * Genesis Plus + * CD data controller (LC89510 compatible) + * + * Copyright (C) 2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ +#ifndef _HW_CDC_ +#define _HW_CDC_ + +#define cdc scd.cdc_hw + +/* CDC hardware */ +typedef struct +{ + uint8 ifstat; + uint8 ifctrl; + reg16_t dbc; + reg16_t dac; + reg16_t pt; + reg16_t wa; + uint8 ctrl[2]; + uint8 head[2][4]; + uint8 stat[4]; + int cycles; + void (*dma_w)(unsigned int words); /* DMA transfer callback */ + uint8 ram[0x4000 + 2352]; /* 16K external RAM (with one block overhead to handle buffer overrun) */ +} cdc_t; + +/* Function prototypes */ +extern void cdc_init(void); +extern void cdc_reset(void); +extern int cdc_context_save(uint8 *state); +extern int cdc_context_load(uint8 *state); +extern void cdc_dma_update(void); +extern int cdc_decoder_update(uint32 header); +extern void cdc_reg_w(unsigned char data); +extern unsigned char cdc_reg_r(void); +extern unsigned short cdc_host_r(void); + +#endif diff --git a/genplus-gx/core/cd_hw/cdd.c b/genplus-gx/core/cd_hw/cdd.c new file mode 100644 index 0000000000..1f2933bb8d --- /dev/null +++ b/genplus-gx/core/cd_hw/cdd.c @@ -0,0 +1,1740 @@ +/*************************************************************************************** + * Genesis Plus + * CD drive processor & CD-DA fader + * + * Copyright (C) 2012-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ +#include "shared.h" + +#ifdef USE_LIBTREMOR +#define SUPPORTED_EXT 20 +#else +#define SUPPORTED_EXT 10 +#endif + +/* BCD conversion lookup tables */ +static const uint8 lut_BCD_8[100] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, +}; + +static const uint16 lut_BCD_16[100] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, 0x0109, + 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, 0x0206, 0x0207, 0x0208, 0x0209, + 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, 0x0309, + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, + 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507, 0x0508, 0x0509, + 0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, 0x0606, 0x0607, 0x0608, 0x0609, + 0x0700, 0x0701, 0x0702, 0x0703, 0x0704, 0x0705, 0x0706, 0x0707, 0x0708, 0x0709, + 0x0800, 0x0801, 0x0802, 0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, + 0x0900, 0x0901, 0x0902, 0x0903, 0x0904, 0x0905, 0x0906, 0x0907, 0x0908, 0x0909, +}; + +/* pre-build TOC */ +static const uint16 toc_snatcher[21] = +{ + 56014, 495, 10120, 20555, 1580, 5417, 12502, 16090, 6553, 9681, + 8148, 20228, 8622, 6142, 5858, 1287, 7424, 3535, 31697, 2485, + 31380 +}; + +static const uint16 toc_lunar[52] = +{ + 5422, 1057, 7932, 5401, 6380, 6592, 5862, 5937, 5478, 5870, + 6673, 6613, 6429, 4996, 4977, 5657, 3720, 5892, 3140, 3263, + 6351, 5187, 3249, 1464, 1596, 1750, 1751, 6599, 4578, 5205, + 1550, 1827, 2328, 1346, 1569, 1613, 7199, 4928, 1656, 2549, + 1875, 3901, 1850, 2399, 2028, 1724, 4889, 14551, 1184, 2132, + 685, 3167 +}; + +static const uint32 toc_shadow[15] = +{ + 10226, 70054, 11100, 12532, 12444, 11923, 10059, 10167, 10138, 13792, + 11637, 2547, 2521, 3856, 900 +}; + +static const uint32 toc_dungeon[13] = +{ + 2250, 22950, 16350, 24900, 13875, 19950, 13800, 15375, 17400, 17100, + 3325, 6825, 25275 +}; + +static const uint32 toc_ffight[26] = +{ + 11994, 9742, 10136, 9685, 9553, 14588, 9430, 8721, 9975, 9764, + 9704, 12796, 585, 754, 951, 624, 9047, 1068, 817, 9191, 1024, + 14562, 10320, 8627, 3795, 3047 +}; + +static const uint32 toc_ffightj[29] = +{ + 11994, 9752, 10119, 9690, 9567, 14575, 9431, 8731, 9965, 9763, + 9716, 12791, 579, 751, 958, 630, 9050, 1052, 825, 9193, 1026, + 14553, 9834, 10542, 1699, 1792, 1781, 3783, 3052 +}; + +/* supported WAVE file header (16-bit stereo samples @44.1kHz) */ +static const unsigned char waveHeader[32] = +{ + 0x57,0x41,0x56,0x45,0x66,0x6d,0x74,0x20,0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00, + 0x44,0xac,0x00,0x00,0x10,0xb1,0x02,0x00,0x04,0x00,0x10,0x00,0x64,0x61,0x74,0x61 +}; + +/* supported WAVE file extensions */ +static const char extensions[SUPPORTED_EXT][16] = +{ +#ifdef USE_LIBTREMOR + "%02d.ogg", + " %02d.ogg", + "-%02d.ogg", + "_%02d.ogg", + " - %02d.ogg", + "%d.ogg", + " %d.ogg", + "-%d.ogg", + "_%d.ogg", + " - %d.ogg", +#endif + "%02d.wav", + " %02d.wav", + "-%02d.wav", + "_%02d.wav", + " - %02d.wav", + "%d.wav", + " %d.wav", + "-%d.wav", + "_%d.wav", + " - %d.wav" +}; + +static blip_t* blip[2]; + + +#ifdef USE_LIBTREMOR +#ifdef DISABLE_MANY_OGG_OPEN_FILES +static void ogg_free(int i) +{ + /* clear OGG file descriptor to prevent file from being closed */ + cdd.toc.tracks[i].vf.datasource = NULL; + + /* close VORBIS file structure */ + ov_clear(&cdd.toc.tracks[i].vf); + + /* indicates that the track is a seekable VORBIS file */ + cdd.toc.tracks[i].vf.seekable = 1; + + /* reset file reading position */ + fseek(cdd.toc.tracks[i].fd, 0, SEEK_SET); +} +#endif +#endif + +void cdd_init(blip_t* left, blip_t* right) +{ + /* CD-DA is running by default at 44100 Hz */ + /* Audio stream is resampled to desired rate using Blip Buffer */ + blip[0] = left; + blip[1] = right; + blip_set_rates(left, 44100, snd.sample_rate); + blip_set_rates(right, 44100, snd.sample_rate); +} + +void cdd_reset(void) +{ + /* reset cycle counter */ + cdd.cycles = 0; + + /* reset drive access latency */ + cdd.latency = 0; + + /* reset track index */ + cdd.index = 0; + + /* reset logical block address */ + cdd.lba = 0; + + /* reset status */ + cdd.status = cdd.loaded ? CD_STOP : NO_DISC; + + /* reset CD-DA fader (full volume) */ + cdd.volume = 0x400; + + /* clear CD-DA output */ + cdd.audio[0] = cdd.audio[1] = 0; +} + +int cdd_context_save(uint8 *state) +{ + int bufferptr = 0; + + save_param(&cdd.cycles, sizeof(cdd.cycles)); + save_param(&cdd.latency, sizeof(cdd.latency)); + save_param(&cdd.index, sizeof(cdd.index)); + save_param(&cdd.lba, sizeof(cdd.lba)); + save_param(&cdd.scanOffset, sizeof(cdd.scanOffset)); + save_param(&cdd.volume, sizeof(cdd.volume)); + save_param(&cdd.status, sizeof(cdd.status)); + + return bufferptr; +} + +int cdd_context_load(uint8 *state) +{ + int lba; + int bufferptr = 0; + +#ifdef USE_LIBTREMOR +#ifdef DISABLE_MANY_OGG_OPEN_FILES + /* close previous track VORBIS file structure to save memory */ + if (cdd.toc.tracks[cdd.index].vf.datasource) + { + ogg_free(cdd.index); + } +#endif +#endif + + load_param(&cdd.cycles, sizeof(cdd.cycles)); + load_param(&cdd.latency, sizeof(cdd.latency)); + load_param(&cdd.index, sizeof(cdd.index)); + load_param(&cdd.lba, sizeof(cdd.lba)); + load_param(&cdd.scanOffset, sizeof(cdd.scanOffset)); + load_param(&cdd.volume, sizeof(cdd.volume)); + load_param(&cdd.status, sizeof(cdd.status)); + + /* adjust current LBA within track limit */ + lba = cdd.lba; + if (lba < cdd.toc.tracks[cdd.index].start) + { + lba = cdd.toc.tracks[cdd.index].start; + } + + /* seek to current track position */ + if (!cdd.index) + { + /* DATA track */ + if (cdd.toc.tracks[0].fd) + { + fseek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET); + } + } +#ifdef USE_LIBTREMOR + else if (cdd.toc.tracks[cdd.index].vf.seekable) + { +#ifdef DISABLE_MANY_OGG_OPEN_FILES + /* VORBIS file need to be opened first */ + ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0); +#endif + /* VORBIS AUDIO track */ + ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba - cdd.toc.tracks[cdd.index].start) * 588 - cdd.toc.tracks[cdd.index].offset); + } +#endif + else if (cdd.toc.tracks[cdd.index].fd) + { + /* PCM AUDIO track */ + fseek(cdd.toc.tracks[cdd.index].fd, (lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET); + } + + return bufferptr; +} + +int cdd_load(char *filename, char *header) +{ + char fname[256]; + char line[128]; + char *ptr = 0; + char *lptr = 0; + FILE *fd; + + /* first unmount any loaded disc */ + cdd_unload(); + + /* open file */ + fd = fopen(filename, "rb"); + + /* save a copy of base filename */ + strncpy(fname, filename, 256); + + /* autodetect .cue file */ + if (!memcmp(".cue", &filename[strlen(filename) - 4], 4) || !memcmp(".CUE", &filename[strlen(filename) - 4], 4)) + { + if (fd) + { + /* find first FILE command */ + while (!lptr) + { + if (fgets(line, 128, fd) == NULL) + { + break; + } + lptr = strstr(line, "FILE"); + } + + /* get BINARY file name */ + if (lptr && strstr(line, " BINARY")) + { + /* skip "FILE" attribute */ + lptr += 4; + + /* skip DOUBLE QUOTE or SPACE characters */ + while ((*lptr == 0x20) || (*lptr == '\"')) lptr++; + + /* set pointer at the end of filepath */ + ptr = fname + strlen(fname) - 1; + while ((ptr - fname) && (*ptr != '/') && (*ptr != '\\')) ptr--; + if (ptr - fname) ptr++; + + /* append filename characters after filepath */ + while ((*lptr != '\"') && memcmp(lptr, " BINARY", 7) && (ptr < (fname + 255))) + { + *ptr++ = *lptr++; + } + *ptr = 0; + + /* open file & initialize DATA track file descriptor */ + cdd.toc.tracks[0].fd = fopen(fname, "rb"); + } + else + { + /* close .cue file */ + fclose(fd); + + /* invalid .cue file */ + return -1; + } + } + } + else + { + /* initialize DATA track file descriptor */ + cdd.toc.tracks[0].fd = fd; + + /* automatically try to open associated .cue file */ + strncpy(&fname[strlen(fname) - 4], ".cue", 4); + fd = fopen(fname, "rb"); + } + + if (!cdd.toc.tracks[0].fd) + { + /* close any opened .cue file */ + if (fd) fclose(fd); + + /* error opening file */ + return -1; + } + + /* read first 16 bytes */ + fread(header, 0x10, 1, cdd.toc.tracks[0].fd); + + /* look for valid CD image ID string */ + if (memcmp("SEGADISCSYSTEM", header, 14)) + { + /* if not found, read next 16 bytes */ + fread(header, 0x10, 1, cdd.toc.tracks[0].fd); + + /* look again for valid CD image ID string */ + if (memcmp("SEGADISCSYSTEM", header, 14)) + { + /* close any opened .cue file */ + if (fd) fclose(fd); + + /* close binary file */ + fclose(cdd.toc.tracks[0].fd); + cdd.toc.tracks[0].fd = 0; + + /* not a CD image file */ + return 0; + } + + /* BIN format (2352 bytes data blocks) */ + cdd.sectorSize = 2352; + } + else + { + /* ISO format (2048 bytes data blocks) */ + cdd.sectorSize = 2048; + } + + /* read CD image header + security code */ + fread(header + 0x10, 0x200, 1, cdd.toc.tracks[0].fd); + + /* DATA track start time (based on DATA file length) */ + fseek(cdd.toc.tracks[0].fd, 0, SEEK_END); + cdd.toc.tracks[0].end = ftell(cdd.toc.tracks[0].fd) / cdd.sectorSize; + + /* DATA track start time (logical block 0) */ + fseek(cdd.toc.tracks[0].fd, 0, SEEK_SET); + cdd.toc.tracks[0].start = 0; + + /* initialize TOC */ + cdd.toc.end = cdd.toc.tracks[0].end; + cdd.toc.last = 1; + + /* automatically retrieve audio tracks infos from .cue file */ + if (fd) + { + int pregap = 0; + int mm, ss, bb; + + /* skip first (DATA) track */ + while (!strstr(line, "INDEX 01") && !strstr(line, "INDEX 1")) + { + if (fgets(line, 128, fd) == NULL) + { + break; + } + } + + /* read next lines until end of file */ + while (fgets(line, 128, fd) != NULL) + { + /* skip any SPACE characters */ + lptr = line; + while (*lptr == 0x20) lptr++; + + /* decode FILE commands */ + if (!(memcmp(lptr, "FILE", 4))) + { + /* skip "FILE" attribute */ + lptr += 4; + + /* skip DOUBLE QUOTE or SPACE characters */ + while ((*lptr == 0x20) || (*lptr == '\"')) lptr++; + + /* set pointer at the end of filepath */ + ptr = fname + strlen(fname) - 1; + while ((ptr - fname) && (*ptr != '/') && (*ptr != '\\')) ptr--; + if (ptr - fname) ptr++; + + /* append filename characters after filepath */ + while ((*lptr != '\"') && (lptr <= (line + 128)) && (ptr < (fname + 255))) + { + *ptr++ = *lptr++; + } + *ptr = 0; + + /* open file & initialize track file descriptor */ + cdd.toc.tracks[cdd.toc.last].fd = fopen(fname, "rb"); + if (!cdd.toc.tracks[cdd.toc.last].fd) + { + /* error opening file */ + break; + } + + /* reset current file PREGAP length */ + pregap = 0; + + /* reset current file read offset */ + cdd.toc.tracks[cdd.toc.last].offset = 0; + + /* check supported file types */ + if (!strstr(lptr,"BINARY")) + { + /* read file header */ + unsigned char head[32]; + fseek(cdd.toc.tracks[cdd.toc.last].fd, 8, SEEK_SET); + fread(head, 32, 1, cdd.toc.tracks[cdd.toc.last].fd); + fseek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET); + + /* autodetect WAVE file header (16-bit stereo @44.1kHz only) */ + if (!memcmp(head, waveHeader, 32)) + { + /* adjust current track file read offset with WAVE header length */ + cdd.toc.tracks[cdd.toc.last].offset -= 44; + } + #ifdef USE_LIBTREMOR + else if (!ov_open(cdd.toc.tracks[cdd.toc.last].fd,&cdd.toc.tracks[cdd.toc.last].vf,0,0)) + { + /* retrieve stream infos */ + vorbis_info *info = ov_info(&cdd.toc.tracks[cdd.toc.last].vf,-1); + if (!info || (info->rate != 44100) || (info->channels != 2)) + { + /* unsupported VORBIS file format (stereo @44.1kHz only) */ + ov_clear(&cdd.toc.tracks[cdd.toc.last].vf); + cdd.toc.tracks[cdd.toc.last].fd = 0; + break; + } + } +#endif + else + { + /* unsupported audio file */ + fclose(cdd.toc.tracks[cdd.toc.last].fd); + cdd.toc.tracks[cdd.toc.last].fd = 0; + break; + } + } + } + + /* decode TRACK commands */ + else if ((sscanf(lptr, "TRACK %02d AUDIO", &bb)) || (sscanf(lptr, "TRACK %d AUDIO", &bb))) + { + /* check track number */ + if (bb != (cdd.toc.last + 1)) + { + /* close any opened file */ + if (cdd.toc.tracks[cdd.toc.last].fd) + { + fclose(cdd.toc.tracks[cdd.toc.last].fd); + cdd.toc.tracks[cdd.toc.last].fd = 0; + } + + /* missing tracks */ + break; + } + + /* check if a single file is used for all tracks */ + if (!cdd.toc.tracks[cdd.toc.last].fd) + { + /* clear previous track end time */ + cdd.toc.tracks[cdd.toc.last - 1].end = 0; + } + } + + /* decode PREGAP commands */ + else if (sscanf(lptr, "PREGAP %02d:%02d:%02d", &mm, &ss, &bb) == 3) + { + /* increment current file PREGAP length */ + pregap += bb + ss*75 + mm*60*75; + } + + /* decode INDEX commands */ + else if ((sscanf(lptr, "INDEX 00 %02d:%02d:%02d", &mm, &ss, &bb) == 3) || + (sscanf(lptr, "INDEX 0 %02d:%02d:%02d", &mm, &ss, &bb) == 3)) + { + /* check if a single file is used for all tracks */ + if (!cdd.toc.tracks[cdd.toc.last].fd) + { + /* set previous track end time */ + cdd.toc.tracks[cdd.toc.last - 1].end = bb + ss*75 + mm*60*75 + pregap; + } + } + else if ((sscanf(lptr, "INDEX 01 %02d:%02d:%02d", &mm, &ss, &bb) == 3) || + (sscanf(lptr, "INDEX 1 %02d:%02d:%02d", &mm, &ss, &bb) == 3)) + { + /* adjust file read offset for current track with current file PREGAP length */ + cdd.toc.tracks[cdd.toc.last].offset += pregap * 2352; + + /* check if a single file is used for all tracks */ + if (!cdd.toc.tracks[cdd.toc.last].fd) + { + /* use common file descriptor */ + cdd.toc.tracks[cdd.toc.last].fd = cdd.toc.tracks[0].fd; + + /* current track start time (based on current absolute time) */ + cdd.toc.tracks[cdd.toc.last].start = bb + ss*75 + mm*60*75 + pregap; + + /* check if previous track end time has not been already set (through INDEX00 command) */ + if (cdd.toc.tracks[cdd.toc.last - 1].end == 0) + { + /* set previous track end time (based on current absolute timee) */ + cdd.toc.tracks[cdd.toc.last - 1].end = bb + ss*75 + mm*60*75; + } + } + else + { + /* current track start time (based on previous track end time) */ + cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end + bb + ss*75 + mm*60*75 + pregap; + + /* adjust file read offset with previous track end time */ + cdd.toc.tracks[cdd.toc.last].offset += cdd.toc.end * 2352; + + #ifdef USE_LIBTREMOR + if (cdd.toc.tracks[cdd.toc.last].vf.datasource) + { + /* convert read offset to PCM sample offset */ + cdd.toc.tracks[cdd.toc.last].offset = cdd.toc.tracks[cdd.toc.last].offset / 4; + + /* current track end time */ + cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ov_pcm_total(&cdd.toc.tracks[cdd.toc.last].vf,-1)/588; + if (cdd.toc.tracks[cdd.toc.last].end <= cdd.toc.tracks[cdd.toc.last].start) + { + /* invalid length */ + ov_clear(&cdd.toc.tracks[cdd.toc.last].vf); + cdd.toc.tracks[cdd.toc.last].fd = 0; + cdd.toc.tracks[cdd.toc.last].end = 0; + cdd.toc.tracks[cdd.toc.last].start = 0; + cdd.toc.tracks[cdd.toc.last].offset = 0; + break; + } + +#ifdef DISABLE_MANY_OGG_OPEN_FILES + /* close VORBIS file structure to save memory */ + ogg_free(cdd.toc.last); +#endif + } + else +#endif + { + /* current track end time */ + fseek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_END); + cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((ftell(cdd.toc.tracks[cdd.toc.last].fd) + 2351) / 2352); + fseek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET); + } + + /* update TOC end */ + cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end; + } + + /* increment track number */ + cdd.toc.last++; + } + } + + /* check if a single file is used for all tracks */ + if (cdd.toc.tracks[cdd.toc.last - 1].fd == cdd.toc.tracks[0].fd) + { + /* adjust TOC end */ + cdd.toc.end += pregap; + + /* last track end index */ + cdd.toc.tracks[cdd.toc.last - 1].end = cdd.toc.end; + } + + /* close .cue file */ + fclose(fd); + } + + /* .ISO audio tracks auto-detection */ + else if (cdd.sectorSize == 2048) + { + int i, offset; + + /* set pointer at the end of filename */ + ptr = fname + strlen(fname) - 4; + + /* auto-detect track file extensions */ + for (i=0; irate != 44100) || (info->channels != 2)) + { + /* unsupported OGG file */ + ov_clear(&cdd.toc.tracks[cdd.toc.last].vf); + break; + } + + /* initialize current track file descriptor */ + cdd.toc.tracks[cdd.toc.last].fd = fd; + + /* initialize current track start time (based on previous track end time) */ + cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end; + + /* add default 2s PAUSE between tracks */ + cdd.toc.tracks[cdd.toc.last].start += 150; + + /* current track end time */ + cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ov_pcm_total(&cdd.toc.tracks[cdd.toc.last].vf,-1)/588; + if (cdd.toc.tracks[cdd.toc.last].end <= cdd.toc.tracks[cdd.toc.last].start) + { + /* invalid file length */ + ov_clear(&cdd.toc.tracks[cdd.toc.last].vf); + cdd.toc.tracks[cdd.toc.last].fd = 0; + cdd.toc.tracks[cdd.toc.last].end = 0; + cdd.toc.tracks[cdd.toc.last].start = 0; + break; + } + + /* auto-detect PAUSE within audio files */ + ov_pcm_seek(&cdd.toc.tracks[cdd.toc.last].vf, 100 * 588); + ov_read(&cdd.toc.tracks[cdd.toc.last].vf, (char *)head, 32, 0); + ov_pcm_seek(&cdd.toc.tracks[cdd.toc.last].vf, 0); + if (*(int32 *)head == 0) + { + /* assume 2s PAUSE is included at the beginning of the file */ + cdd.toc.tracks[cdd.toc.last].offset -= 150 * 588; + cdd.toc.tracks[cdd.toc.last].end -= 150; + } + +#ifdef DISABLE_MANY_OGG_OPEN_FILES + /* close VORBIS file structure to save memory */ + ogg_free(cdd.toc.last); +#endif + + /* update TOC end */ + cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end; + + /* increment track number */ + cdd.toc.last++; + } +#endif + else + { + /* unsupported audio file format */ + fclose(fd); + break; + } + + /* try to open next audio track file */ + sprintf(ptr, extensions[i], cdd.toc.last + offset); + fd = fopen(fname, "rb"); + } + } + + /* Simulate audio tracks if none found */ + if (cdd.toc.last == 1) + { + /* Some games require exact TOC infos */ + if (strstr(header + 0x180,"T-95035") != NULL) + { + /* Snatcher */ + cdd.toc.last = cdd.toc.end = 0; + do + { + cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end; + cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_snatcher[cdd.toc.last]; + cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end; + cdd.toc.last++; + } + while (cdd.toc.last < 21); + } + else if (strstr(header + 0x180,"T-127015") != NULL) + { + /* Lunar - The Silver Star */ + cdd.toc.last = cdd.toc.end = 0; + do + { + cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end; + cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_lunar[cdd.toc.last]; + cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end; + cdd.toc.last++; + } + while (cdd.toc.last < 52); + } + else if (strstr(header + 0x180,"T-113045") != NULL) + { + /* Shadow of the Beast II */ + cdd.toc.last = cdd.toc.end = 0; + do + { + cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end; + cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_shadow[cdd.toc.last]; + cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end; + cdd.toc.last++; + } + while (cdd.toc.last < 15); + } + else if (strstr(header + 0x180,"T-143025") != NULL) + { + /* Dungeon Explorer */ + cdd.toc.last = cdd.toc.end = 0; + do + { + cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end; + cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_dungeon[cdd.toc.last]; + cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end; + cdd.toc.last++; + } + while (cdd.toc.last < 13); + } + else if (strstr(header + 0x180,"MK-4410") != NULL) + { + /* Final Fight CD (USA, Europe) */ + cdd.toc.last = cdd.toc.end = 0; + do + { + cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end; + cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_ffight[cdd.toc.last]; + cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end; + cdd.toc.last++; + } + while (cdd.toc.last < 26); + } + else if (strstr(header + 0x180,"G-6013") != NULL) + { + /* Final Fight CD (Japan) */ + cdd.toc.last = cdd.toc.end = 0; + do + { + cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end; + cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_ffightj[cdd.toc.last]; + cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end; + cdd.toc.last++; + } + while (cdd.toc.last < 29); + } + else + { + /* default TOC (99 tracks & 2s per audio tracks) */ + do + { + cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end + 2*75; + cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + 2*75; + cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end; + cdd.toc.last++; + } + while ((cdd.toc.last < 99) && (cdd.toc.end < 56*60*75)); + } + } + + /* Lead-out */ + cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end; + + /* CD loaded */ + cdd.loaded = 1; + return 1; +} + +void cdd_unload(void) +{ + if (cdd.loaded) + { + int i; + + /* close CD tracks */ + for (i=0; i= 0) && (cdd.lba < cdd.toc.tracks[0].end)) + { + /* BIN format ? */ + if (cdd.sectorSize == 2352) + { + /* skip 16-byte header */ + fseek(cdd.toc.tracks[0].fd, cdd.lba * 2352 + 16, SEEK_SET); + } + + /* read sector data (Mode 1 = 2048 bytes) */ + fread(dst, 2048, 1, cdd.toc.tracks[0].fd); + } +} + +void cdd_read_audio(unsigned int samples) +{ + /* previous audio outputs */ + int16 l = cdd.audio[0]; + int16 r = cdd.audio[1]; + + /* get number of internal clocks (samples) needed */ + samples = blip_clocks_needed(blip[0], samples); + + /* audio track playing ? */ + if (!scd.regs[0x36>>1].byte.h && cdd.toc.tracks[cdd.index].fd) + { + int i, mul, delta; + + /* current CD-DA fader volume */ + int curVol = cdd.volume; + + /* CD-DA fader volume setup (0-1024) */ + int endVol = scd.regs[0x34>>1].w >> 4; + + /* read samples from current block */ +#ifdef USE_LIBTREMOR + if (cdd.toc.tracks[cdd.index].vf.datasource) + { + int len, done = 0; + int16 *ptr = (int16 *) (cdc.ram); + samples = samples * 4; + while (done < samples) + { + len = ov_read(&cdd.toc.tracks[cdd.index].vf, (char *)(cdc.ram + done), samples - done, 0); + if (len <= 0) + { + done = samples; + break; + } + done += len; + } + samples = done / 4; + + /* process 16-bit (host-endian) stereo samples */ + for (i=0; i endVol) + { + /* fade-out */ + curVol--; + } + else if (!curVol) + { + /* audio will remain muted until next setup */ + break; + } + } + } + else +#endif + { +#ifdef LSB_FIRST + int16 *ptr = (int16 *) (cdc.ram); +#else + uint8 *ptr = cdc.ram; +#endif + fread(cdc.ram, 1, samples * 4, cdd.toc.tracks[cdd.index].fd); + + /* process 16-bit (little-endian) stereo samples */ + for (i=0; i endVol) + { + /* fade-out */ + curVol--; + } + else if (!curVol) + { + /* audio will remain muted until next setup */ + break; + } + } + } + + /* save current CD-DA fader volume */ + cdd.volume = curVol; + + /* save last audio output for next frame */ + cdd.audio[0] = l; + cdd.audio[1] = r; + } + else + { + /* no audio output */ + if (l) blip_add_delta_fast(blip[0], 0, -l); + if (r) blip_add_delta_fast(blip[1], 0, -r); + + /* save audio output for next frame */ + cdd.audio[0] = 0; + cdd.audio[1] = 0; + } + + /* end of Blip Buffer timeframe */ + blip_end_frame(blip[0], samples); + blip_end_frame(blip[1], samples); +} + + +void cdd_update(void) +{ +#ifdef LOG_CDD + error("LBA = %d (track n°%d)(latency=%d)\n", cdd.lba, cdd.index, cdd.latency); +#endif + + /* seeking disc */ + if (cdd.status == CD_SEEK) + { + /* drive latency */ + if (cdd.latency > 0) + { + cdd.latency--; + return; + } + + /* drive is ready */ + cdd.status = CD_READY; + } + + /* reading disc */ + else if (cdd.status == CD_PLAY) + { + /* drive latency */ + if (cdd.latency > 0) + { + cdd.latency--; + return; + } + + /* track type */ + if (!cdd.index) + { + /* DATA sector header (CD-ROM Mode 1) */ + uint8 header[4]; + uint32 msf = cdd.lba + 150; + header[0] = lut_BCD_8[(msf / 75) / 60]; + header[1] = lut_BCD_8[(msf / 75) % 60]; + header[2] = lut_BCD_8[(msf % 75)]; + header[3] = 0x01; + + /* data track sector read is controlled by CDC */ + cdd.lba += cdc_decoder_update(*(uint32 *)(header)); + } + else if (cdd.index < cdd.toc.last) + { + /* check against audio track start index */ + if (cdd.lba >= cdd.toc.tracks[cdd.index].start) + { + /* audio track playing */ + scd.regs[0x36>>1].byte.h = 0x00; + } + + /* audio blocks are still sent to CDC as well as CD DAC/Fader */ + cdc_decoder_update(0); + + /* next audio block is automatically read */ + cdd.lba++; + } + else + { + /* end of disc */ + cdd.status = CD_END; + return; + } + + /* check end of current track */ + if (cdd.lba >= cdd.toc.tracks[cdd.index].end) + { +#ifdef USE_LIBTREMOR +#ifdef DISABLE_MANY_OGG_OPEN_FILES + /* close previous track VORBIS file structure to save memory */ + if (cdd.toc.tracks[cdd.index].vf.datasource) + { + ogg_free(cdd.index); + } +#endif +#endif + /* play next track */ + cdd.index++; + + /* PAUSE between tracks */ + scd.regs[0x36>>1].byte.h = 0x01; + + /* seek to next audio track start */ +#ifdef USE_LIBTREMOR + if (cdd.toc.tracks[cdd.index].vf.seekable) + { +#ifdef DISABLE_MANY_OGG_OPEN_FILES + /* VORBIS file need to be opened first */ + ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0); +#endif + ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, -cdd.toc.tracks[cdd.index].offset); + } + else +#endif + if (cdd.toc.tracks[cdd.index].fd) + { + fseek(cdd.toc.tracks[cdd.index].fd, (cdd.toc.tracks[cdd.index].start * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET); + } + } + } + + /* scanning disc */ + else if (cdd.status == CD_SCAN) + { + /* fast-forward or fast-rewind */ + cdd.lba += cdd.scanOffset; + + /* check current track limits */ + if (cdd.lba >= cdd.toc.tracks[cdd.index].end) + { +#ifdef USE_LIBTREMOR +#ifdef DISABLE_MANY_OGG_OPEN_FILES + /* close previous track VORBIS file structure to save memory */ + if (cdd.toc.tracks[cdd.index].vf.datasource) + { + ogg_free(cdd.index); + } +#endif +#endif + /* next track */ + cdd.index++; + + /* skip directly to track start position */ + cdd.lba = cdd.toc.tracks[cdd.index].start; + + /* AUDIO track playing ? */ + if (cdd.status == CD_PLAY) + { + scd.regs[0x36>>1].byte.h = 0x00; + } + } + else if (cdd.lba < cdd.toc.tracks[cdd.index].start) + { +#ifdef USE_LIBTREMOR +#ifdef DISABLE_MANY_OGG_OPEN_FILES + /* close previous track VORBIS file structure to save memory */ + if (cdd.toc.tracks[cdd.index].vf.datasource) + { + ogg_free(cdd.index); + } +#endif +#endif + + /* previous track */ + cdd.index--; + + /* skip directly to track end position */ + cdd.lba = cdd.toc.tracks[cdd.index].end; + } + + /* check disc limits */ + if (cdd.index < 0) + { + cdd.index = 0; + cdd.lba = 0; + } + else if (cdd.index >= cdd.toc.last) + { + /* no AUDIO track playing */ + scd.regs[0x36>>1].byte.h = 0x01; + + /* end of disc */ + cdd.index = cdd.toc.last; + cdd.lba = cdd.toc.end; + cdd.status = CD_END; + return; + } + + /* seek to current block */ + if (!cdd.index) + { + /* no AUDIO track playing */ + scd.regs[0x36>>1].byte.h = 0x01; + + /* DATA track */ + fseek(cdd.toc.tracks[0].fd, cdd.lba * cdd.sectorSize, SEEK_SET); + } +#ifdef USE_LIBTREMOR + else if (cdd.toc.tracks[cdd.index].vf.seekable) + { +#ifdef DISABLE_MANY_OGG_OPEN_FILES + /* check if a new track is being played */ + if (!cdd.toc.tracks[cdd.index].vf.datasource) + { + /* VORBIS file need to be opened first */ + ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0); + } +#endif + /* VORBIS AUDIO track */ + ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (cdd.lba - cdd.toc.tracks[cdd.index].start) * 588 - cdd.toc.tracks[cdd.index].offset); + } +#endif + else if (cdd.toc.tracks[cdd.index].fd) + { + /* PCM AUDIO track */ + fseek(cdd.toc.tracks[cdd.index].fd, (cdd.lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET); + } + } +} + +void cdd_process(void) +{ + /* Process CDD command */ + switch (scd.regs[0x42>>1].byte.h & 0x0f) + { + case 0x00: /* Drive Status */ + { + /* RS1-RS8 normally unchanged */ + scd.regs[0x38>>1].byte.h = cdd.status; + + /* unless RS1 indicated invalid track infos */ + if (scd.regs[0x38>>1].byte.l == 0x0f) + { + /* and SEEK has ended */ + if (cdd.status != CD_SEEK) + { + /* then return valid track infos, e.g current track number in RS2-RS3 (fixes Lunar - The Silver Star) */ + scd.regs[0x38>>1].byte.l = 0x02; + scd.regs[0x3a>>1].w = (cdd.index < cdd.toc.last) ? lut_BCD_16[cdd.index + 1] : 0x0A0A; + } + } + break; + } + + case 0x01: /* Stop Drive */ + { + /* update status */ + cdd.status = cdd.loaded ? CD_STOP : NO_DISC; + + /* no audio track playing */ + scd.regs[0x36>>1].byte.h = 0x01; + + /* RS1-RS8 ignored, expects 0x0 ("no disc" ?) in RS0 once */ + scd.regs[0x38>>1].w = 0x0000; + scd.regs[0x3a>>1].w = 0x0000; + scd.regs[0x3c>>1].w = 0x0000; + scd.regs[0x3e>>1].w = 0x0000; + scd.regs[0x40>>1].w = 0x000f; + return; + } + + case 0x02: /* Read TOC */ + { + /* Infos automatically retrieved by CDD processor from Q-Channel */ + /* commands 0x00-0x02 (current block) and 0x03-0x05 (Lead-In) */ + switch (scd.regs[0x44>>1].byte.l) + { + case 0x00: /* Current Absolute Time (MM:SS:FF) */ + { + int lba = cdd.lba + 150; + scd.regs[0x38>>1].w = cdd.status << 8; + scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60]; + scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60]; + scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)]; + scd.regs[0x40>>1].byte.h = cdd.index ? 0x00 : 0x04; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */ + break; + } + + case 0x01: /* Current Track Relative Time (MM:SS:FF) */ + { + int lba = cdd.lba - cdd.toc.tracks[cdd.index].start; + scd.regs[0x38>>1].w = (cdd.status << 8) | 0x01; + scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60]; + scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60]; + scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)]; + scd.regs[0x40>>1].byte.h = cdd.index ? 0x00 : 0x04; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */ + break; + } + + case 0x02: /* Current Track Number */ + { + scd.regs[0x38>>1].w = (cdd.status << 8) | 0x02; + scd.regs[0x3a>>1].w = (cdd.index < cdd.toc.last) ? lut_BCD_16[cdd.index + 1] : 0x0A0A; + scd.regs[0x3c>>1].w = 0x0000; + scd.regs[0x3e>>1].w = 0x0000; /* Disk Control Code (?) in RS6 */ + scd.regs[0x40>>1].byte.h = 0x00; + break; + } + + case 0x03: /* Total length (MM:SS:FF) */ + { + int lba = cdd.toc.end + 150; + scd.regs[0x38>>1].w = (cdd.status << 8) | 0x03; + scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60]; + scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60]; + scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)]; + scd.regs[0x40>>1].byte.h = 0x00; + break; + } + + case 0x04: /* First & Last Track Numbers */ + { + scd.regs[0x38>>1].w = (cdd.status << 8) | 0x04; + scd.regs[0x3a>>1].w = 0x0001; + scd.regs[0x3c>>1].w = lut_BCD_16[cdd.toc.last]; + scd.regs[0x3e>>1].w = 0x0000; /* Drive Version (?) in RS6-RS7 */ + scd.regs[0x40>>1].byte.h = 0x00; /* Lead-In flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */ + break; + } + + case 0x05: /* Track Start Time (MM:SS:FF) */ + { + int track = scd.regs[0x46>>1].byte.h * 10 + scd.regs[0x46>>1].byte.l; + int lba = cdd.toc.tracks[track-1].start + 150; + scd.regs[0x38>>1].w = (cdd.status << 8) | 0x05; + scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60]; + scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60]; + scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)]; + scd.regs[0x40>>1].byte.h = track % 10; /* Track Number (low digit) */ + if (track == 1) + { + /* RS6 bit 3 is set for the first (DATA) track */ + scd.regs[0x3e>>1].byte.h |= 0x08; + } + break; + } + + default: + { +#ifdef LOG_ERROR + error("Unknown CDD Command %02X (%X)\n", scd.regs[0x44>>1].byte.l, s68k.pc); +#endif + return; + } + } + break; + } + + case 0x03: /* Play */ + { + /* reset track index */ + int index = 0; + + /* new LBA position */ + int lba = ((scd.regs[0x44>>1].byte.h * 10 + scd.regs[0x44>>1].byte.l) * 60 + + (scd.regs[0x46>>1].byte.h * 10 + scd.regs[0x46>>1].byte.l)) * 75 + + (scd.regs[0x48>>1].byte.h * 10 + scd.regs[0x48>>1].byte.l) - 150; + + /* CD drive latency */ + if (!cdd.latency) + { + /* Fixes a few games hanging during intro because they expect data to be read with some delay */ + /* Radical Rex needs at least one interrupt delay */ + /* Wolf Team games (Anet Futatabi, Cobra Command, Road Avenger & Time Gal) need at least 6 interrupts delay */ + /* Space Adventure Cobra (2nd morgue scene) needs at least 13 interrupts delay (incl. seek time, so 6 is OK) */ + /* Jeopardy & ESPN Sunday Night NFL are picky about this as well: 10 interrupts delay (+ seek time) seems OK */ + cdd.latency = 10; + } + + /* CD drive seek time */ + /* max. seek time = 1.5 s = 1.5 x 75 = 112.5 CDD interrupts (rounded to 120) for 270000 sectors max on disc. */ + /* Note: This is only a rough approximation since, on real hardware, seek time is much likely not linear and */ + /* latency much larger than above value, but this model works fine for Sonic CD (track 26 playback needs to */ + /* be enough delayed to start in sync with intro sequence, as compared with real hardware recording). */ + if (lba > cdd.lba) + { + cdd.latency += (((lba - cdd.lba) * 120) / 270000); + } + else + { + cdd.latency += (((cdd.lba - lba) * 120) / 270000); + } + + /* update current LBA */ + cdd.lba = lba; + + /* get track index */ + while ((cdd.toc.tracks[index].end <= lba) && (index < cdd.toc.last)) index++; + +#ifdef USE_LIBTREMOR +#ifdef DISABLE_MANY_OGG_OPEN_FILES + /* check if track index has changed */ + if (index != cdd.index) + { + /* close previous track VORBIS file structure to save memory */ + if (cdd.toc.tracks[cdd.index].vf.datasource) + { + ogg_free(cdd.index); + } + + /* open current track VORBIS file */ + if (cdd.toc.tracks[index].vf.seekable) + { + ov_open(cdd.toc.tracks[index].fd,&cdd.toc.tracks[index].vf,0,0); + } + } +#endif +#endif + + /* update current track index */ + cdd.index = index; + + /* stay within track limits when seeking files */ + if (lba < cdd.toc.tracks[index].start) + { + lba = cdd.toc.tracks[index].start; + } + + /* seek to current block */ + if (!index) + { + /* DATA track */ + fseek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET); + } +#ifdef USE_LIBTREMOR + else if (cdd.toc.tracks[index].vf.seekable) + { + /* VORBIS AUDIO track */ + ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba - cdd.toc.tracks[index].start) * 588 - cdd.toc.tracks[index].offset); + } +#endif + else if (cdd.toc.tracks[index].fd) + { + /* PCM AUDIO track */ + fseek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET); + } + + /* no audio track playing (yet) */ + scd.regs[0x36>>1].byte.h = 0x01; + + /* update status */ + cdd.status = CD_PLAY; + + /* return track index in RS2-RS3 */ + scd.regs[0x38>>1].w = (CD_PLAY << 8) | 0x02; + scd.regs[0x3a>>1].w = (cdd.index < cdd.toc.last) ? lut_BCD_16[index + 1] : 0x0A0A; + scd.regs[0x3c>>1].w = 0x0000; + scd.regs[0x3e>>1].w = 0x0000; + scd.regs[0x40>>1].byte.h = 0x00; + break; + } + + case 0x04: /* Seek */ + { + /* reset track index */ + int index = 0; + + /* new LBA position */ + int lba = ((scd.regs[0x44>>1].byte.h * 10 + scd.regs[0x44>>1].byte.l) * 60 + + (scd.regs[0x46>>1].byte.h * 10 + scd.regs[0x46>>1].byte.l)) * 75 + + (scd.regs[0x48>>1].byte.h * 10 + scd.regs[0x48>>1].byte.l) - 150; + + /* CD drive seek time */ + /* We are using similar linear model as above, although still not exactly accurate, */ + /* it works fine for Switch/Panic! intro (Switch needs at least 30 interrupts while */ + /* seeking from 00:05:63 to 24:03:19, Panic! when seeking from 00:05:60 to 24:06:07) */ + if (lba > cdd.lba) + { + cdd.latency = ((lba - cdd.lba) * 120) / 270000; + } + else + { + cdd.latency = ((cdd.lba - lba) * 120) / 270000; + } + + /* update current LBA */ + cdd.lba = lba; + + /* get current track index */ + while ((cdd.toc.tracks[index].end <= lba) && (index < cdd.toc.last)) index++; + +#ifdef USE_LIBTREMOR +#ifdef DISABLE_MANY_OGG_OPEN_FILES + /* check if track index has changed */ + if (index != cdd.index) + { + /* close previous track VORBIS file structure to save memory */ + if (cdd.toc.tracks[cdd.index].vf.datasource) + { + ogg_free(cdd.index); + } + + /* open current track VORBIS file */ + if (cdd.toc.tracks[index].vf.seekable) + { + ov_open(cdd.toc.tracks[index].fd,&cdd.toc.tracks[index].vf,0,0); + } + } +#endif +#endif + + /* update current track index */ + cdd.index = index; + + /* stay within track limits */ + if (lba < cdd.toc.tracks[index].start) + { + lba = cdd.toc.tracks[index].start; + } + + /* seek to current block */ + if (!index) + { + /* DATA track */ + fseek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET); + } +#ifdef USE_LIBTREMOR + else if (cdd.toc.tracks[index].vf.seekable) + { + /* VORBIS AUDIO track */ + ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba - cdd.toc.tracks[index].start) * 588 - cdd.toc.tracks[index].offset); + } +#endif + else if (cdd.toc.tracks[index].fd) + { + /* PCM AUDIO track */ + fseek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET); + } + + /* no audio track playing */ + scd.regs[0x36>>1].byte.h = 0x01; + + /* update status */ + cdd.status = CD_SEEK; + + /* unknown RS1-RS8 values (returning 0xF in RS1 invalidates track infos in RS2-RS8 and fixes Final Fight CD intro when seek time is emulated) */ + scd.regs[0x38>>1].w = (CD_SEEK << 8) | 0x0f; + scd.regs[0x3a>>1].w = 0x0000; + scd.regs[0x3c>>1].w = 0x0000; + scd.regs[0x3e>>1].w = 0x0000; + scd.regs[0x40>>1].w = ~(CD_SEEK + 0xf) & 0x0f; + return; + } + + case 0x06: /* Pause */ + { + /* no audio track playing */ + scd.regs[0x36>>1].byte.h = 0x01; + + /* update status (RS1-RS8 unchanged) */ + cdd.status = scd.regs[0x38>>1].byte.h = CD_READY; + break; + } + + case 0x07: /* Resume */ + { + /* update status (RS1-RS8 unchanged) */ + cdd.status = scd.regs[0x38>>1].byte.h = CD_PLAY; + break; + } + + case 0x08: /* Forward Scan */ + { + /* reset scanning direction / speed */ + cdd.scanOffset = CD_SCAN_SPEED; + + /* update status (RS1-RS8 unchanged) */ + cdd.status = scd.regs[0x38>>1].byte.h = CD_SCAN; + break; + } + + case 0x09: /* Rewind Scan */ + { + /* reset scanning direction / speed */ + cdd.scanOffset = -CD_SCAN_SPEED; + + /* update status (RS1-RS8 unchanged) */ + cdd.status = scd.regs[0x38>>1].byte.h = CD_SCAN; + break; + } + + + case 0x0a: /* N-Track Jump Control ? (usually sent before CD_SEEK or CD_PLAY commands) */ + { + /* TC3 corresponds to seek direction (00=forward, FF=reverse) */ + /* TC4-TC7 are related to seek length (4x4 bits i.e parameter values are between -65535 and +65535) */ + /* Maybe related to number of auto-sequenced track jumps/moves for CD DSP (cf. CXD2500BQ datasheet) */ + /* also see US Patent nr. 5222054 for a detailled description of seeking operation using Track Jump */ + + /* no audio track playing */ + scd.regs[0x36>>1].byte.h = 0x01; + + /* update status (RS1-RS8 unchanged) */ + cdd.status = scd.regs[0x38>>1].byte.h = CD_READY; + break; + } + + case 0x0c: /* Close Tray */ + { + /* no audio track playing */ + scd.regs[0x36>>1].byte.h = 0x01; + + /* update status */ + cdd.status = cdd.loaded ? CD_STOP : NO_DISC; + + /* RS1-RS8 ignored, expects 0x0 ("no disc" ?) in RS0 once */ + scd.regs[0x38>>1].w = 0x0000; + scd.regs[0x3a>>1].w = 0x0000; + scd.regs[0x3c>>1].w = 0x0000; + scd.regs[0x3e>>1].w = 0x0000; + scd.regs[0x40>>1].w = 0x000f; + +#ifdef CD_TRAY_CALLBACK + CD_TRAY_CALLBACK +#endif + return; + } + + case 0x0d: /* Open Tray */ + { + /* no audio track playing */ + scd.regs[0x36>>1].byte.h = 0x01; + + /* update status (RS1-RS8 ignored) */ + cdd.status = CD_OPEN; + scd.regs[0x38>>1].w = CD_OPEN << 8; + scd.regs[0x3a>>1].w = 0x0000; + scd.regs[0x3c>>1].w = 0x0000; + scd.regs[0x3e>>1].w = 0x0000; + scd.regs[0x40>>1].w = ~CD_OPEN & 0x0f; + +#ifdef CD_TRAY_CALLBACK + CD_TRAY_CALLBACK +#endif + return; + } + + default: /* Unknown command */ +#ifdef LOG_CDD + error("Unknown CDD Command !!!\n"); +#endif + scd.regs[0x38>>1].byte.h = cdd.status; + break; + } + + /* only compute checksum when necessary */ + scd.regs[0x40>>1].byte.l = ~(scd.regs[0x38>>1].byte.h + scd.regs[0x38>>1].byte.l + + scd.regs[0x3a>>1].byte.h + scd.regs[0x3a>>1].byte.l + + scd.regs[0x3c>>1].byte.h + scd.regs[0x3c>>1].byte.l + + scd.regs[0x3e>>1].byte.h + scd.regs[0x3e>>1].byte.l + + scd.regs[0x40>>1].byte.h) & 0x0f; +} diff --git a/genplus-gx/core/cd_hw/cdd.h b/genplus-gx/core/cd_hw/cdd.h new file mode 100644 index 0000000000..b3f53df5d9 --- /dev/null +++ b/genplus-gx/core/cd_hw/cdd.h @@ -0,0 +1,112 @@ +/*************************************************************************************** + * Genesis Plus + * CD drive processor & CD-DA fader + * + * Copyright (C) 2012-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ +#ifndef _HW_CDD_ +#define _HW_CDD_ + +#include "blip_buf.h" + +#ifdef USE_LIBTREMOR +#include "tremor/ivorbisfile.h" +#endif + +#define cdd scd.cdd_hw + +/* CDD status */ +#define NO_DISC 0x00 +#define CD_PLAY 0x01 +#define CD_SEEK 0x02 +#define CD_SCAN 0x03 +#define CD_READY 0x04 +#define CD_OPEN 0x05 /* similar to 0x0E ? */ +#define CD_STOP 0x09 +#define CD_END 0x0C + +/* CD blocks scanning speed */ +#define CD_SCAN_SPEED 30 + +#define CD_MAX_TRACKS 100 + +/* CD track */ +typedef struct +{ + FILE *fd; +#ifdef USE_LIBTREMOR + OggVorbis_File vf; +#endif + int offset; + int start; + int end; +} track_t; + +/* CD TOC */ +typedef struct +{ + int end; + int last; + track_t tracks[CD_MAX_TRACKS]; +} toc_t; + +/* CDD hardware */ +typedef struct +{ + uint32 cycles; + uint32 latency; + int loaded; + int index; + int lba; + int scanOffset; + int volume; + uint8 status; + uint16 sectorSize; + toc_t toc; + int16 audio[2]; +} cdd_t; + +/* Function prototypes */ +extern void cdd_init(blip_t* left, blip_t* right); +extern void cdd_reset(void); +extern int cdd_context_save(uint8 *state); +extern int cdd_context_load(uint8 *state); +extern int cdd_load(char *filename, char *header); +extern void cdd_unload(void); +extern void cdd_read_data(uint8 *dst); +extern void cdd_read_audio(unsigned int samples); +extern void cdd_update(void); +extern void cdd_process(void); + +#endif diff --git a/genplus-gx/core/cd_hw/gfx.c b/genplus-gx/core/cd_hw/gfx.c new file mode 100644 index 0000000000..ca43a6701d --- /dev/null +++ b/genplus-gx/core/cd_hw/gfx.c @@ -0,0 +1,729 @@ +/*************************************************************************************** + * Genesis Plus + * CD graphics processor + * + * Copyright (C) 2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ +#include "shared.h" + +/***************************************************************/ +/* WORD-RAM DMA interfaces (1M & 2M modes) */ +/***************************************************************/ + +void word_ram_0_dma_w(unsigned int words) +{ + uint16 data; + + /* CDC buffer source address */ + uint16 src_index = cdc.dac.w & 0x3ffe; + + /* WORD-RAM destination address*/ + uint32 dst_index = (scd.regs[0x0a>>1].w << 3) & 0x1fffe; + + /* update DMA destination address */ + scd.regs[0x0a>>1].w += (words >> 2); + + /* update DMA source address */ + cdc.dac.w += (words << 1); + + /* DMA transfer */ + while (words--) + { + /* read 16-bit word from CDC buffer */ + data = *(uint16 *)(cdc.ram + src_index); + +#ifdef LSB_FIRST + /* source data is stored in big endian format */ + data = ((data >> 8) | (data << 8)) & 0xffff; +#endif + + /* write 16-bit word to WORD-RAM */ + *(uint16 *)(scd.word_ram[0] + dst_index) = data ; + + /* increment CDC buffer source address */ + src_index = (src_index + 2) & 0x3ffe; + + /* increment WORD-RAM destination address */ + dst_index = (dst_index + 2) & 0x1fffe; + } +} + +void word_ram_1_dma_w(unsigned int words) +{ + uint16 data; + + /* CDC buffer source address */ + uint16 src_index = cdc.dac.w & 0x3ffe; + + /* WORD-RAM destination address*/ + uint32 dst_index = ((scd.regs[0x0a>>1].w << 3) & 0x1fffe); + + /* update DMA destination address */ + scd.regs[0x0a>>1].w += (words >> 2); + + /* update DMA source address */ + cdc.dac.w += (words << 1); + + /* DMA transfer */ + while (words--) + { + /* read 16-bit word from CDC buffer */ + data = *(uint16 *)(cdc.ram + src_index); + +#ifdef LSB_FIRST + /* source data is stored in big endian format */ + data = ((data >> 8) | (data << 8)) & 0xffff; +#endif + + /* write 16-bit word to WORD-RAM */ + *(uint16 *)(scd.word_ram[1] + dst_index) = data ; + + /* increment CDC buffer source address */ + src_index = (src_index + 2) & 0x3ffe; + + /* increment WORD-RAM destination address */ + dst_index = (dst_index + 2) & 0x1fffe; + } +} + +void word_ram_2M_dma_w(unsigned int words) +{ + uint16 data; + + /* CDC buffer source address */ + uint16 src_index = cdc.dac.w & 0x3ffe; + + /* WORD-RAM destination address*/ + uint32 dst_index = (scd.regs[0x0a>>1].w << 3) & 0x3fffe; + + /* update DMA destination address */ + scd.regs[0x0a>>1].w += (words >> 2); + + /* update DMA source address */ + cdc.dac.w += (words << 1); + + /* DMA transfer */ + while (words--) + { + /* read 16-bit word from CDC buffer */ + data = *(uint16 *)(cdc.ram + src_index); + +#ifdef LSB_FIRST + /* source data is stored in big endian format */ + data = ((data >> 8) | (data << 8)) & 0xffff; +#endif + + /* write 16-bit word to WORD-RAM */ + *(uint16 *)(scd.word_ram_2M + dst_index) = data ; + + /* increment CDC buffer source address */ + src_index = (src_index + 2) & 0x3ffe; + + /* increment WORD-RAM destination address */ + dst_index = (dst_index + 2) & 0x3fffe; + } +} + + +/***************************************************************/ +/* WORD-RAM 0 & 1 DOT image SUB-CPU interface (1M Mode) */ +/***************************************************************/ + +unsigned int dot_ram_0_read16(unsigned int address) +{ + uint8 data = READ_BYTE(scd.word_ram[0], (address >> 1) & 0x1ffff); + return ((data & 0x0f) | ((data << 4) & 0xf00)); +} + +unsigned int dot_ram_1_read16(unsigned int address) +{ + uint8 data = READ_BYTE(scd.word_ram[1], (address >> 1) & 0x1ffff); + return ((data & 0x0f) | ((data << 4) & 0xf00)); +} + +void dot_ram_0_write16(unsigned int address, unsigned int data) +{ + uint8 prev; + address = (address >> 1) & 0x1ffff; + prev = READ_BYTE(scd.word_ram[0], address); + data = (data & 0x0f) | ((data >> 4) & 0xf0); + data = gfx.lut_prio[(scd.regs[0x02>>1].w >> 3) & 0x03][prev][data]; + WRITE_BYTE(scd.word_ram[0], address, data); +} + +void dot_ram_1_write16(unsigned int address, unsigned int data) +{ + uint8 prev; + address = (address >> 1) & 0x1ffff; + prev = READ_BYTE(scd.word_ram[1], address); + data = (data & 0x0f) | ((data >> 4) & 0xf0); + data = gfx.lut_prio[(scd.regs[0x02>>1].w >> 3) & 0x03][prev][data]; + WRITE_BYTE(scd.word_ram[1], address, data); +} + +unsigned int dot_ram_0_read8(unsigned int address) +{ + uint8 data = READ_BYTE(scd.word_ram[0], (address >> 1) & 0x1ffff); + + if (address & 1) + { + return (data & 0x0f); + } + + return (data >> 4); +} + +unsigned int dot_ram_1_read8(unsigned int address) +{ + uint8 data = READ_BYTE(scd.word_ram[1], (address >> 1) & 0x1ffff); + + if (address & 1) + { + return (data & 0x0f); + } + + return (data >> 4); +} + +void dot_ram_0_write8(unsigned int address, unsigned int data) +{ + uint8 prev = READ_BYTE(scd.word_ram[0], (address >> 1) & 0x1ffff); + + if (address & 1) + { + data = (prev & 0xf0) | (data & 0x0f); + } + else + { + data = (prev & 0x0f) | (data << 4); + } + + data = gfx.lut_prio[(scd.regs[0x02>>1].w >> 3) & 0x03][prev][data]; + WRITE_BYTE(scd.word_ram[0], (address >> 1) & 0x1ffff, data); +} + +void dot_ram_1_write8(unsigned int address, unsigned int data) +{ + uint8 prev = READ_BYTE(scd.word_ram[1], (address >> 1) & 0x1ffff); + + if (address & 1) + { + data = (prev & 0xf0) | (data & 0x0f); + } + else + { + data = (prev & 0x0f) | (data << 4); + } + + data = gfx.lut_prio[(scd.regs[0x02>>1].w >> 3) & 0x03][prev][data]; + WRITE_BYTE(scd.word_ram[1], (address >> 1) & 0x1ffff, data); +} + + +/***************************************************************/ +/* WORD-RAM 0 & 1 CELL image MAIN-CPU interface (1M Mode) */ +/***************************************************************/ + +unsigned int cell_ram_0_read16(unsigned int address) +{ + address = gfx.lut_offset[(address >> 2) & 0x7fff] | (address & 0x10002); + return *(uint16 *)(scd.word_ram[0] + address); +} + +unsigned int cell_ram_1_read16(unsigned int address) +{ + address = gfx.lut_offset[(address >> 2) & 0x7fff] | (address & 0x10002); + return *(uint16 *)(scd.word_ram[1] + address); +} + +void cell_ram_0_write16(unsigned int address, unsigned int data) +{ + address = gfx.lut_offset[(address >> 2) & 0x7fff] | (address & 0x10002); + *(uint16 *)(scd.word_ram[0] + address) = data; +} + +void cell_ram_1_write16(unsigned int address, unsigned int data) +{ + address = gfx.lut_offset[(address >> 2) & 0x7fff] | (address & 0x10002); + *(uint16 *)(scd.word_ram[1] + address) = data; +} + +unsigned int cell_ram_0_read8(unsigned int address) +{ + address = gfx.lut_offset[(address >> 2) & 0x7fff] | (address & 0x10003); + return READ_BYTE(scd.word_ram[0], address); +} + +unsigned int cell_ram_1_read8(unsigned int address) +{ + address = gfx.lut_offset[(address >> 2) & 0x7fff] | (address & 0x10003); + return READ_BYTE(scd.word_ram[1], address); +} + +void cell_ram_0_write8(unsigned int address, unsigned int data) +{ + address = gfx.lut_offset[(address >> 2) & 0x7fff] | (address & 0x10003); + WRITE_BYTE(scd.word_ram[0], address, data); +} + +void cell_ram_1_write8(unsigned int address, unsigned int data) +{ + address = gfx.lut_offset[(address >> 2) & 0x7fff] | (address & 0x10003); + WRITE_BYTE(scd.word_ram[1], address, data); +} + + +/***************************************************************/ +/* Rotation / Scaling operation (2M Mode) */ +/***************************************************************/ + +void gfx_init(void) +{ + int i, j; + uint16 offset; + uint8 mask, row, col, temp; + + memset(&gfx, 0, sizeof(gfx_t)); + + /* Initialize cell image lookup table */ + /* $220000-$22FFFF corresponds to $200000-$20FFFF */ + for (i=0; i<0x4000; i++) + { + offset = (i & 0x07) << 8; /* cell vline (0-7) */ + offset = offset | (((i >> 8) & 0x3f) << 2); /* cell x offset (0-63) */ + offset = offset | (((i >> 3) & 0x1f) << 11); /* cell y offset (0-31) */ + gfx.lut_offset[i] = offset; + } + + /* $230000-$237FFF corresponds to $210000-$217FFF */ + for (i=0x4000; i<0x6000; i++) + { + offset = (i & 0x07) << 8; /* cell vline (0-7) */ + offset = offset | (((i >> 7) & 0x3f) << 2); /* cell x offset (0-63) */ + offset = offset | (((i >> 3) & 0x0f) << 11); /* cell y offset (0-15) */ + gfx.lut_offset[i] = offset; + } + + /* $238000-$23BFFF corresponds to $218000-$21BFFF */ + for (i=0x6000; i<0x7000; i++) + { + offset = (i & 0x07) << 8; /* cell vline (0-7) */ + offset = offset | (((i >> 6) & 0x3f) << 2); /* cell x offset (0-63) */ + offset = offset | (((i >> 3) & 0x07) << 11); /* cell y offset (0-7) */ + gfx.lut_offset[i] = offset | 0x8000; + } + + /* $23C000-$23DFFF corresponds to $21C000-$21DFFF */ + for (i=0x7000; i<0x7800; i++) + { + offset = (i & 0x07) << 8; /* cell vline (0-7) */ + offset = offset | (((i >> 5) & 0x3f) << 2); /* cell x offset (0-63) */ + offset = offset | (((i >> 3) & 0x03) << 11); /* cell y offset (0-3) */ + gfx.lut_offset[i] = offset | 0xc000; + } + + /* $23E000-$23FFFF corresponds to $21E000-$21FFFF */ + for (i=0x7800; i<0x8000; i++) + { + offset = (i & 0x07) << 8; /* cell vline (0-7) */ + offset = offset | (((i >> 5) & 0x3f) << 2); /* cell x offset (0-63) */ + offset = offset | (((i >> 3) & 0x03) << 11); /* cell y offset (0-3) */ + gfx.lut_offset[i] = offset | 0xe000; + } + + /* Initialize priority modes lookup table */ + for (i=0; i<0x100; i++) + { + for (j=0; j<0x100; j++) + { + /* normal */ + gfx.lut_prio[0][i][j] = j; + /* underwrite */ + gfx.lut_prio[1][i][j] = ((i & 0x0f) ? (i & 0x0f) : (j & 0x0f)) | ((i & 0xf0) ? (i & 0xf0) : (j & 0xf0)); + /* overwrite */ + gfx.lut_prio[2][i][j] = ((j & 0x0f) ? (j & 0x0f) : (i & 0x0f)) | ((j & 0xf0) ? (j & 0xf0) : (i & 0xf0)); + /* invalid */ + gfx.lut_prio[3][i][j] = i; + } + } + + /* Initialize cell lookup table */ + /* table entry = yyxxshrr (8 bits) */ + /* with: yy = cell row (0-3) */ + /* xx = cell column (0-3) */ + /* s = stamp size (0=16x16, 1=32x32) */ + /* hrr = HFLIP & ROTATION bits */ + for (i=0; i<0x100; i++) + { + /* one stamp = 2x2 cells (16x16) or 4x4 cells (32x32) */ + mask = (i & 8) ? 3 : 1; + row = (i >> 6) & mask; + col = (i >> 4) & mask; + + if (i & 4) { col = col ^ mask; } /* HFLIP (always first) */ + if (i & 2) { col = col ^ mask; row = row ^ mask; } /* ROLL1 */ + if (i & 1) { temp = col; col = row ^ mask; row = temp; } /* ROLL0 */ + + /* cell offset (0-3 or 0-15) */ + gfx.lut_cell[i] = row + col * (mask + 1); + } + + /* Initialize pixel lookup table */ + /* table entry = yyyxxxhrr (9 bits) */ + /* with: yyy = pixel row (0-7) */ + /* xxx = pixel column (0-7) */ + /* hrr = HFLIP & ROTATION bits */ + for (i=0; i<0x200; i++) + { + /* one cell = 8x8 pixels */ + row = (i >> 6) & 7; + col = (i >> 3) & 7; + + if (i & 4) { col = col ^ 7; } /* HFLIP (always first) */ + if (i & 2) { col = col ^ 7; row = row ^ 7; } /* ROLL1 */ + if (i & 1) { temp = col; col = row ^ 7; row = temp; } /* ROLL0 */ + + /* pixel offset (0-63) */ + gfx.lut_pixel[i] = col + row * 8; + } +} + +void gfx_reset(void) +{ + /* Reset cycle counter */ + gfx.cycles = 0; +} + +int gfx_context_save(uint8 *state) +{ + uint32 tmp32; + int bufferptr = 0; + + save_param(&gfx.cycles, sizeof(gfx.cycles)); + save_param(&gfx.cyclesPerLine, sizeof(gfx.cyclesPerLine)); + save_param(&gfx.dotMask, sizeof(gfx.dotMask)); + save_param(&gfx.stampShift, sizeof(gfx.stampShift)); + save_param(&gfx.mapShift, sizeof(gfx.mapShift)); + save_param(&gfx.bufferOffset, sizeof(gfx.bufferOffset)); + save_param(&gfx.bufferStart, sizeof(gfx.bufferStart)); + + tmp32 = (uint8 *)(gfx.tracePtr) - scd.word_ram_2M; + save_param(&tmp32, 4); + + tmp32 = (uint8 *)(gfx.mapPtr) - scd.word_ram_2M; + save_param(&tmp32, 4); + + return bufferptr; +} + +int gfx_context_load(uint8 *state) +{ + uint32 tmp32; + int bufferptr = 0; + + load_param(&gfx.cycles, sizeof(gfx.cycles)); + load_param(&gfx.cyclesPerLine, sizeof(gfx.cyclesPerLine)); + load_param(&gfx.dotMask, sizeof(gfx.dotMask)); + load_param(&gfx.stampShift, sizeof(gfx.stampShift)); + load_param(&gfx.mapShift, sizeof(gfx.mapShift)); + load_param(&gfx.bufferOffset, sizeof(gfx.bufferOffset)); + load_param(&gfx.bufferStart, sizeof(gfx.bufferStart)); + + load_param(&tmp32, 4); + gfx.tracePtr = (uint16 *)(scd.word_ram_2M + tmp32); + + load_param(&tmp32, 4); + gfx.mapPtr = (uint16 *)(scd.word_ram_2M + tmp32); + + return bufferptr; +} + +INLINE void gfx_render(uint32 bufferIndex, uint32 width) +{ + uint8 pixel_in, pixel_out; + uint16 stamp_data; + uint32 stamp_index; + + /* pixel map start position for current line (13.3 format converted to 13.11) */ + uint32 xpos = *gfx.tracePtr++ << 8; + uint32 ypos = *gfx.tracePtr++ << 8; + + /* pixel map offset values for current line (5.11 format) */ + uint32 xoffset = (int16) *gfx.tracePtr++; + uint32 yoffset = (int16) *gfx.tracePtr++; + + /* process all dots */ + while (width--) + { + /* check if stamp map is repeated */ + if (scd.regs[0x58>>1].byte.l & 0x01) + { + /* stamp map range */ + xpos &= gfx.dotMask; + ypos &= gfx.dotMask; + } + else + { + /* 24-bit range */ + xpos &= 0xffffff; + ypos &= 0xffffff; + } + + /* check if pixel is outside stamp map */ + if ((xpos | ypos) & ~gfx.dotMask) + { + /* force pixel output to 0 */ + pixel_out = 0x00; + } + else + { + /* read stamp map table data */ + stamp_data = gfx.mapPtr[(xpos >> gfx.stampShift) | ((ypos >> gfx.stampShift) << gfx.mapShift)]; + + /* stamp generator base index */ + /* sss ssssssss ccyyyxxx (16x16) or sss sssssscc ccyyyxxx (32x32) */ + /* with: s = stamp number (1 stamp = 16x16 or 32x32 pixels) */ + /* c = cell offset (0-3 for 16x16, 0-15 for 32x32) */ + /* yyy = line offset (0-7) */ + /* xxx = pixel offset (0-7) */ + stamp_index = (stamp_data & 0x7ff) << 8; + + if (stamp_index) + { + /* extract HFLIP & ROTATION bits */ + stamp_data = (stamp_data >> 13) & 7; + + /* cell offset (0-3 or 0-15) */ + /* table entry = yyxxshrr (8 bits) */ + /* with: yy = cell row (0-3) = (ypos >> (11 + 3)) & 3 */ + /* xx = cell column (0-3) = (xpos >> (11 + 3)) & 3 */ + /* s = stamp size (0=16x16, 1=32x32) */ + /* hrr = HFLIP & ROTATION bits */ + stamp_index |= gfx.lut_cell[stamp_data | ((scd.regs[0x58>>1].byte.l & 0x02) << 2 ) | ((ypos >> 8) & 0xc0) | ((xpos >> 10) & 0x30)] << 6; + + /* pixel offset (0-63) */ + /* table entry = yyyxxxhrr (9 bits) */ + /* with: yyy = pixel row (0-7) = (ypos >> 11) & 7 */ + /* xxx = pixel column (0-7) = (xpos >> 11) & 7 */ + /* hrr = HFLIP & ROTATION bits */ + stamp_index |= gfx.lut_pixel[stamp_data | ((xpos >> 8) & 0x38) | ((ypos >> 5) & 0x1c0)]; + + /* read pixel pair (2 pixels/byte) */ + pixel_out = READ_BYTE(scd.word_ram_2M, stamp_index >> 1); + + /* extract left or rigth pixel */ + if (stamp_index & 1) + { + pixel_out &= 0x0f; + } + else + { + pixel_out >>= 4; + } + } + else + { + /* stamp 0 is not used: force pixel output to 0 */ + pixel_out = 0x00; + } + } + + /* read out paired pixel data */ + pixel_in = READ_BYTE(scd.word_ram_2M, bufferIndex >> 1); + + /* update left or rigth pixel */ + if (bufferIndex & 1) + { + pixel_out |= (pixel_in & 0xf0); + } + else + { + pixel_out = (pixel_out << 4) | (pixel_in & 0x0f); + } + + /* priority mode write */ + pixel_out = gfx.lut_prio[(scd.regs[0x02>>1].w >> 3) & 0x03][pixel_in][pixel_out]; + + /* write data to image buffer */ + WRITE_BYTE(scd.word_ram_2M, bufferIndex >> 1, pixel_out); + + /* check current pixel position */ + if ((bufferIndex & 7) != 7) + { + /* next pixel */ + bufferIndex++; + } + else + { + /* next cell: increment image buffer offset by one column (minus 7 pixels) */ + bufferIndex += gfx.bufferOffset; + } + + /* increment pixel position */ + xpos += xoffset; + ypos += yoffset; + } +} + +void gfx_start(unsigned int base, int cycles) +{ + /* make sure 2M mode is enabled */ + if (!(scd.regs[0x02>>1].byte.l & 0x04)) + { + uint32 mask; + + /* trace vector pointer */ + gfx.tracePtr = (uint16 *)(scd.word_ram_2M + ((base << 2) & 0x3fff8)); + + /* stamps & stamp map size */ + switch ((scd.regs[0x58>>1].byte.l >> 1) & 0x03) + { + case 0: + gfx.dotMask = 0x07ffff; /* 256x256 dots/map */ + gfx.stampShift = 11 + 4; /* 16x16 dots/stamps */ + gfx.mapShift = 4; /* 16x16 stamps/map */ + mask = 0x3fe00; /* 512 bytes/table */ + break; + + case 1: + gfx.dotMask = 0x07ffff; /* 256x256 dots/map */ + gfx.stampShift = 11 + 5; /* 32x32 dots/stamps */ + gfx.mapShift = 3; /* 8x8 stamps/map */ + mask = 0x3ff80; /* 128 bytes/table */ + break; + + case 2: + gfx.dotMask = 0x7fffff; /* 4096*4096 dots/map */ + gfx.stampShift = 11 + 4; /* 16x16 dots/stamps */ + gfx.mapShift = 8; /* 256x256 stamps/map */ + mask = 0x20000; /* 131072 bytes/table */ + break; + + case 3: + gfx.dotMask = 0x7fffff; /* 4096*4096 dots/map */ + gfx.stampShift = 11 + 5; /* 32x32 dots/stamps */ + gfx.mapShift = 7; /* 128x128 stamps/map */ + mask = 0x38000; /* 32768 bytes/table */ + break; + } + + /* stamp map table base address */ + gfx.mapPtr = (uint16 *)(scd.word_ram_2M + ((scd.regs[0x5a>>1].w << 2) & mask)); + + /* image buffer column offset (64 pixels/cell, minus 7 pixels to restart at cell beginning) */ + gfx.bufferOffset = (((scd.regs[0x5c>>1].byte.l & 0x1f) + 1) << 6) - 7; + + /* image buffer start index in dot units (2 pixels/byte) */ + gfx.bufferStart = (scd.regs[0x5e>>1].w << 3) & 0x7ffc0; + + /* add image buffer horizontal dot offset */ + gfx.bufferStart += (scd.regs[0x60>>1].byte.l & 0x3f); + + /* reset GFX chip cycle counter */ + gfx.cycles = cycles; + + /* update GFX chip timings (see AC3:Thunderhawk / Thunderstrike) */ + gfx.cyclesPerLine = 4 * 5 * scd.regs[0x62>>1].w; + + /* start graphics operation */ + scd.regs[0x58>>1].byte.h = 0x80; + } +} + +void gfx_update(int cycles) +{ + /* synchronize GFX chip with SUB-CPU */ + cycles -= gfx.cycles; + + /* make sure SUB-CPU is ahead */ + if (cycles > 0) + { + /* number of lines to process */ + unsigned int lines = (cycles + gfx.cyclesPerLine - 1) / gfx.cyclesPerLine; + + /* check against remaining lines */ + if (lines < scd.regs[0x64>>1].byte.l) + { + /* update Vdot remaining size */ + scd.regs[0x64>>1].byte.l -= lines; + + /* increment cycle counter */ + gfx.cycles += lines * gfx.cyclesPerLine; + } + else + { + /* process remaining lines */ + lines = scd.regs[0x64>>1].byte.l; + + /* clear Vdot remaining size */ + scd.regs[0x64>>1].byte.l = 0; + + /* end of graphics operation */ + scd.regs[0x58>>1].byte.h = 0; + + /* SUB-CPU idle on register $58 polling ? */ + if (s68k.stopped & (1<<0x08)) + { + /* sync SUB-CPU with GFX chip */ + s68k.cycles = scd.cycles; + + /* restart SUB-CPU */ + s68k.stopped = 0; +#ifdef LOG_SCD + error("s68k started from %d cycles\n", s68k.cycles); +#endif + } + + /* level 1 interrupt enabled ? */ + if (scd.regs[0x32>>1].byte.l & 0x02) + { + /* trigger level 1 interrupt */ + scd.pending |= (1 << 1); + + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + + /* render lines */ + while (lines--) + { + /* process dots to image buffer */ + gfx_render(gfx.bufferStart, scd.regs[0x62>>1].w); + + /* increment image buffer start index for next line (8 pixels/line) */ + gfx.bufferStart += 8; + } + } +} diff --git a/genplus-gx/core/cd_hw/gfx.h b/genplus-gx/core/cd_hw/gfx.h new file mode 100644 index 0000000000..c1ca497efb --- /dev/null +++ b/genplus-gx/core/cd_hw/gfx.h @@ -0,0 +1,116 @@ +/*************************************************************************************** + * Genesis Plus + * CD graphics processor + * + * Copyright (C) 2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ +#ifndef _CD_GFX_ +#define _CD_GFX_ + +#define gfx scd.gfx_hw + +typedef struct +{ + uint32 cycles; /* current cycles count for graphics operation */ + uint32 cyclesPerLine; /* current graphics operation timings */ + uint32 dotMask; /* stamp map size mask */ + uint16 *tracePtr; /* trace vector pointer */ + uint16 *mapPtr; /* stamp map table base address */ + uint8 stampShift; /* stamp pixel shift value (related to stamp size) */ + uint8 mapShift; /* stamp map table shift value (related to stamp map size) */ + uint16 bufferOffset; /* image buffer column offset */ + uint32 bufferStart; /* image buffer start index */ + uint16 lut_offset[0x8000]; /* Cell Image -> WORD-RAM offset lookup table (1M Mode) */ + uint8 lut_prio[4][0x100][0x100]; /* WORD-RAM data writes priority lookup table */ + uint8 lut_pixel[0x200]; /* Graphics operation dot offset lookup table */ + uint8 lut_cell[0x100]; /* Graphics operation stamp offset lookup table */ +} gfx_t; + + +/***************************************************************/ +/* WORD-RAM DMA interfaces (1M & 2M modes) */ +/***************************************************************/ +extern void word_ram_0_dma_w(unsigned int words); +extern void word_ram_1_dma_w(unsigned int words); +extern void word_ram_2M_dma_w(unsigned int words); + +/***************************************************************/ +/* WORD-RAM 0 & 1 CPU interfaces (1M mode) */ +/***************************************************************/ +extern unsigned int word_ram_0_read16(unsigned int address); +extern unsigned int word_ram_1_read16(unsigned int address); +extern void word_ram_0_write16(unsigned int address, unsigned int data); +extern void word_ram_1_write16(unsigned int address, unsigned int data); +extern unsigned int word_ram_0_read8(unsigned int address); +extern unsigned int word_ram_1_read8(unsigned int address); +extern void word_ram_0_write8(unsigned int address, unsigned int data); +extern void word_ram_1_write8(unsigned int address, unsigned int data); + +/***************************************************************/ +/* WORD-RAM 0 & 1 DOT image SUB-CPU interface (1M mode) */ +/***************************************************************/ +extern unsigned int dot_ram_0_read16(unsigned int address); +extern unsigned int dot_ram_1_read16(unsigned int address); +extern void dot_ram_0_write16(unsigned int address, unsigned int data); +extern void dot_ram_1_write16(unsigned int address, unsigned int data); +extern unsigned int dot_ram_0_read8(unsigned int address); +extern unsigned int dot_ram_1_read8(unsigned int address); +extern void dot_ram_0_write8(unsigned int address, unsigned int data); +extern void dot_ram_1_write8(unsigned int address, unsigned int data); + + +/***************************************************************/ +/* WORD-RAM 0 & 1 CELL image MAIN-CPU interface (1M mode) */ +/***************************************************************/ +extern unsigned int cell_ram_0_read16(unsigned int address); +extern unsigned int cell_ram_1_read16(unsigned int address); +extern void cell_ram_0_write16(unsigned int address, unsigned int data); +extern void cell_ram_1_write16(unsigned int address, unsigned int data); +extern unsigned int cell_ram_0_read8(unsigned int address); +extern unsigned int cell_ram_1_read8(unsigned int address); +extern void cell_ram_0_write8(unsigned int address, unsigned int data); +extern void cell_ram_1_write8(unsigned int address, unsigned int data); + + +/***************************************************************/ +/* Rotation / Scaling operation (2M mode) */ +/***************************************************************/ +extern void gfx_init(void); +extern void gfx_reset(void); +extern int gfx_context_save(uint8 *state); +extern int gfx_context_load(uint8 *state); +extern void gfx_start(unsigned int base, int cycles); +extern void gfx_update(int cycles); + +#endif diff --git a/genplus-gx/core/cd_hw/pcm.c b/genplus-gx/core/cd_hw/pcm.c new file mode 100644 index 0000000000..05a2bf91cf --- /dev/null +++ b/genplus-gx/core/cd_hw/pcm.c @@ -0,0 +1,442 @@ +/*************************************************************************************** + * Genesis Plus + * PCM sound chip (315-5476A) (RF5C164 compatible) + * + * Copyright (C) 2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ +#include "shared.h" + +#define PCM_SCYCLES_RATIO (384 * 4) + +#define pcm scd.pcm_hw + +static blip_t* blip[2]; + +void pcm_init(blip_t* left, blip_t* right) +{ + /* number of SCD master clocks run per second */ + double mclk = snd.frame_rate ? (SCYCLES_PER_LINE * (vdp_pal ? 313 : 262) * snd.frame_rate) : SCD_CLOCK; + + /* PCM chips is running at original rate and is synchronized with SUB-CPU */ + /* Chip output is resampled to desired rate using Blip Buffer. */ + blip[0] = left; + blip[1] = right; + blip_set_rates(left, mclk / PCM_SCYCLES_RATIO, snd.sample_rate); + blip_set_rates(right, mclk / PCM_SCYCLES_RATIO, snd.sample_rate); +} + +void pcm_reset(void) +{ + /* reset chip & clear external RAM */ + memset(&pcm, 0, sizeof(pcm_t)); + + /* reset default bank */ + pcm.bank = pcm.ram; + + /* reset channels stereo panning */ + pcm.chan[0].pan = 0xff; + pcm.chan[1].pan = 0xff; + pcm.chan[2].pan = 0xff; + pcm.chan[3].pan = 0xff; + pcm.chan[4].pan = 0xff; + pcm.chan[5].pan = 0xff; + pcm.chan[6].pan = 0xff; + pcm.chan[7].pan = 0xff; + + /* reset master clocks counter */ + pcm.cycles = 0; + + /* clear blip buffers */ + blip_clear(blip[0]); + blip_clear(blip[1]); +} + +int pcm_context_save(uint8 *state) +{ + uint8 tmp8; + int bufferptr = 0; + + tmp8 = (pcm.bank - pcm.ram) >> 12; + + save_param(pcm.chan, sizeof(pcm.chan)); + save_param(pcm.out, sizeof(pcm.out)); + save_param(&tmp8, 1); + save_param(&pcm.enabled, sizeof(pcm.enabled)); + save_param(&pcm.status, sizeof(pcm.status)); + save_param(&pcm.index, sizeof(pcm.index)); + save_param(pcm.ram, sizeof(pcm.ram)); + + return bufferptr; +} + +int pcm_context_load(uint8 *state) +{ + uint8 tmp8; + int bufferptr = 0; + + load_param(pcm.chan, sizeof(pcm.chan)); + load_param(pcm.out, sizeof(pcm.out)); + + load_param(&tmp8, 1); + pcm.bank = &pcm.ram[(tmp8 & 0x0f) << 12]; + + load_param(&pcm.enabled, sizeof(pcm.enabled)); + load_param(&pcm.status, sizeof(pcm.status)); + load_param(&pcm.index, sizeof(pcm.index)); + load_param(pcm.ram, sizeof(pcm.ram)); + + return bufferptr; +} + +void pcm_run(unsigned int length) +{ +#ifdef LOG_PCM + error("[%d][%d]run %d PCM samples (from %d)\n", v_counter, s68k.cycles, length, pcm.cycles); +#endif + /* check if PCM chip is running */ + if (pcm.enabled) + { + int i, j, l, r; + + /* generate PCM samples */ + for (i=0; i> 11) & 0xffff]; + + /* loop data ? */ + if (data == 0xff) + { + /* reset WAVE RAM address */ + pcm.chan[j].addr = pcm.chan[j].ls.w << 11; + + /* read again from WAVE RAM address */ + data = pcm.ram[pcm.chan[j].ls.w]; + } + else + { + /* increment WAVE RAM address */ + pcm.chan[j].addr += pcm.chan[j].fd.w; + } + + /* infinite loop should not output any data */ + if (data != 0xff) + { + /* check sign bit (output centered around 0) */ + if (data & 0x80) + { + /* PCM data is positive */ + data = data & 0x7f; + } + else + { + /* PCM data is negative */ + data = -(data & 0x7f); + } + + /* multiply PCM data with ENV & stereo PAN data then add to L/R outputs (14.5 fixed point) */ + l += ((data * pcm.chan[j].env * (pcm.chan[j].pan & 0x0F)) >> 5); + r += ((data * pcm.chan[j].env * (pcm.chan[j].pan >> 4)) >> 5); + } + } + } + + /* limiter */ + if (l < -32768) l = -32768; + else if (l > 32767) l = 32767; + if (r < -32768) r = -32768; + else if (r > 32767) r = 32767; + + /* check if PCM left output changed */ + if (pcm.out[0] != l) + { + blip_add_delta_fast(blip[0], i, l-pcm.out[0]); + pcm.out[0] = l; + } + + /* check if PCM right output changed */ + if (pcm.out[1] != r) + { + blip_add_delta_fast(blip[1], i, r-pcm.out[1]); + pcm.out[1] = r; + } + } + } + else + { + /* check if PCM left output changed */ + if (pcm.out[0]) + { + blip_add_delta_fast(blip[0], 0, -pcm.out[0]); + pcm.out[0] = 0; + } + + /* check if PCM right output changed */ + if (pcm.out[1]) + { + blip_add_delta_fast(blip[1], 0, -pcm.out[1]); + pcm.out[1] = 0; + } + } + + /* end of blip buffer frame */ + blip_end_frame(blip[0], length); + blip_end_frame(blip[1], length); + + /* update PCM master clock counter */ + pcm.cycles += length * PCM_SCYCLES_RATIO; +} + +void pcm_update(unsigned int samples) +{ + /* get number of internal clocks (samples) needed */ + unsigned int clocks = blip_clocks_needed(blip[0], samples); + + /* run PCM chip */ + if (clocks > 0) + { + pcm_run(clocks); + } + + /* reset PCM master clocks counter */ + pcm.cycles = 0; +} + +void pcm_write(unsigned int address, unsigned char data) +{ + /* synchronize PCM chip with SUB-CPU */ + int clocks = s68k.cycles - pcm.cycles; + if (clocks > 0) + { + /* number of internal clocks (samples) to run */ + clocks = (clocks + PCM_SCYCLES_RATIO - 1) / PCM_SCYCLES_RATIO; + pcm_run(clocks); + } + +#ifdef LOG_PCM + error("[%d][%d]PCM write %x -> 0x%02x (%X)\n", v_counter, s68k.cycles, address, data, s68k.pc); +#endif + + /* external RAM is mapped to $1000-$1FFF */ + if (address >= 0x1000) + { + /* 4K bank access */ + pcm.bank[address & 0xfff] = data; + return; + } + + /* internal area si mapped to $0000-$0FFF */ + switch (address) + { + case 0x00: /* ENV register */ + { + /* update channel ENV multiplier */ + pcm.chan[pcm.index].env = data; + return; + } + + case 0x01: /* PAN register */ + { + /* update channel stereo panning value */ + pcm.chan[pcm.index].pan = data; + return; + } + + case 0x02: /* FD register (LSB) */ + { + /* update channel WAVE RAM address increment LSB */ + pcm.chan[pcm.index].fd.byte.l = data; + return; + } + + case 0x03: /* FD register (MSB) */ + { + /* update channel WAVE RAM address increment MSB */ + pcm.chan[pcm.index].fd.byte.h = data; + return; + } + + case 0x04: /* LS register (LSB) */ + { + /* update channel WAVE RAM loop address LSB */ + pcm.chan[pcm.index].ls.byte.l = data; + return; + } + + case 0x05: /* LS register (MSB) */ + { + /* update channel WAVE RAM loop address MSB */ + pcm.chan[pcm.index].ls.byte.h = data; + return; + } + + case 0x06: /* ST register */ + { + /* update channel WAVE RAM start address (16.11 fixed point) */ + pcm.chan[pcm.index].st = data << (8 + 11); + + /* reload WAVE RAM address if channel is OFF */ + if (!(pcm.status & (1 << pcm.index))) + { + pcm.chan[pcm.index].addr = pcm.chan[pcm.index].st; + } + return; + } + + case 0x07: /* CTRL register */ + { + if (data & 0x40) + { + /* channel selection (0-7) */ + pcm.index = data & 0x07; + } + else + { + /* external RAM bank selection (16 x 4K) */ + pcm.bank = &pcm.ram[(data & 0x0f) << 12]; + } + + /* update PCM chip status (bit 7) */ + pcm.enabled = data & 0x80; + return; + } + + case 0x08: /* ON/OFF register */ + { + /* update PCM channels status */ + pcm.status = ~data; + + /* reload WAVE RAM address pointers when channels are OFF */ + if (data & 0x01) pcm.chan[0].addr = pcm.chan[0].st; + if (data & 0x02) pcm.chan[1].addr = pcm.chan[1].st; + if (data & 0x04) pcm.chan[2].addr = pcm.chan[2].st; + if (data & 0x08) pcm.chan[3].addr = pcm.chan[3].st; + if (data & 0x10) pcm.chan[4].addr = pcm.chan[4].st; + if (data & 0x20) pcm.chan[5].addr = pcm.chan[5].st; + if (data & 0x40) pcm.chan[6].addr = pcm.chan[6].st; + if (data & 0x80) pcm.chan[7].addr = pcm.chan[7].st; + return; + } + + default: + { + /* illegal access */ + return; + } + } +} + +unsigned char pcm_read(unsigned int address) +{ + /* synchronize PCM chip with SUB-CPU */ + int clocks = s68k.cycles - pcm.cycles; + if (clocks > 0) + { + /* number of internal clocks (samples) to run */ + clocks = (clocks + PCM_SCYCLES_RATIO - 1) / PCM_SCYCLES_RATIO; + pcm_run(clocks); + } + +#ifdef LOG_PCM + error("[%d][%d]PCM read (%X)\n", v_counter, s68k.cycles, address, s68k.pc); +#endif + + /* external RAM (TODO: verify if possible to read, some docs claim it's not !) */ + if (address >= 0x1000) + { + /* 4K bank access */ + return pcm.bank[address & 0xfff]; + } + + /* read WAVE RAM address pointers */ + if ((address >= 0x10) && (address < 0x20)) + { + int index = (address >> 1) & 0x07; + + if (address & 1) + { + return (pcm.chan[index].addr >> (11 + 8)) & 0xff; + } + else + { + return (pcm.chan[index].addr >> 11) & 0xff; + } + } + + /* illegal access */ + return 0xff; +} + +void pcm_ram_dma_w(unsigned int words) +{ + uint16 data; + + /* CDC buffer source address */ + uint16 src_index = cdc.dac.w & 0x3ffe; + + /* PCM-RAM destination address*/ + uint16 dst_index = (scd.regs[0x0a>>1].w << 2) & 0xffe; + + /* update DMA destination address */ + scd.regs[0x0a>>1].w += (words >> 1); + + /* update DMA source address */ + cdc.dac.w += (words << 1); + + /* DMA transfer */ + while (words--) + { + /* read 16-bit word from CDC buffer */ + data = *(uint16 *)(cdc.ram + src_index); + + /* write 16-bit word to PCM RAM (endianness does not matter since PCM RAM is always accessed as byte)*/ + *(uint16 *)(pcm.bank + dst_index) = data ; + + /* increment CDC buffer source address */ + src_index = (src_index + 2) & 0x3ffe; + + /* increment PCM-RAM destination address */ + dst_index = (dst_index + 2) & 0xffe; + } +} + diff --git a/genplus-gx/core/cd_hw/pcm.h b/genplus-gx/core/cd_hw/pcm.h new file mode 100644 index 0000000000..d0fe47789b --- /dev/null +++ b/genplus-gx/core/cd_hw/pcm.h @@ -0,0 +1,77 @@ +/*************************************************************************************** + * Genesis Plus + * PCM sound chip (315-5476A) (RF5C164 compatible) + * + * Copyright (C) 2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ +#ifndef _CD_PCM_ +#define _CD_PCM_ + +#include "blip_buf.h" + +/* PCM channel */ +typedef struct +{ + uint32 addr; /* current Wave RAM address (16.11 fixed point) */ + uint32 st; /* Wave RAM start address (16.11 fixed point) */ + reg16_t ls; /* Wave RAM loop address ($0000-$ffff) */ + reg16_t fd; /* Wave RAM address increment (5.11 fixed point) */ + uint8 env; /* enveloppe multiplier */ + uint8 pan; /* stereo panning */ +} chan_t; + +/* PCM sound chip */ +typedef struct +{ + chan_t chan[8]; /* PCM channels 1-8 */ + int16 out[2]; /* previous PCM stereo output */ + uint8 *bank; /* external RAM bank pointer */ + uint8 enabled; /* PCM chip ON/OFF status */ + uint8 status; /* channels ON/OFF status */ + uint8 index; /* current channel index */ + uint8 ram[0x10000]; /* 64k external RAM */ + uint32 cycles; +} pcm_t; + +/* Function prototypes */ +extern void pcm_init(blip_t* left, blip_t* right); +extern void pcm_reset(void); +extern int pcm_context_save(uint8 *state); +extern int pcm_context_load(uint8 *state); +extern void pcm_update(unsigned int samples); +extern void pcm_write(unsigned int address, unsigned char data); +extern unsigned char pcm_read(unsigned int address); +extern void pcm_ram_dma_w(unsigned int words); + +#endif diff --git a/genplus-gx/core/cd_hw/scd.c b/genplus-gx/core/cd_hw/scd.c new file mode 100644 index 0000000000..378ac3f086 --- /dev/null +++ b/genplus-gx/core/cd_hw/scd.c @@ -0,0 +1,1673 @@ +/*************************************************************************************** + * Genesis Plus + * Mega CD / Sega CD hardware + * + * Copyright (C) 2012-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +/*--------------------------------------------------------------------------*/ +/* Unused area (return open bus data, i.e prefetched instruction word) */ +/*--------------------------------------------------------------------------*/ +static unsigned int s68k_read_bus_8(unsigned int address) +{ +#ifdef LOGERROR + error("[SUB 68k] Unused read8 %08X (%08X)\n", address, s68k.pc); +#endif + address = s68k.pc | (address & 1); + return READ_BYTE(s68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff); +} + +static unsigned int s68k_read_bus_16(unsigned int address) +{ +#ifdef LOGERROR + error("[SUB 68k] Unused read16 %08X (%08X)\n", address, s68k.pc); +#endif + address = s68k.pc; + return *(uint16 *)(s68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)); +} + +static void s68k_unused_8_w(unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error("[SUB 68k] Unused write8 %08X = %02X (%08X)\n", address, data, s68k.pc); +#endif +} + +static void s68k_unused_16_w(unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error("[SUB 68k] Unused write16 %08X = %04X (%08X)\n", address, data, s68k.pc); +#endif +} + +/*--------------------------------------------------------------------------*/ +/* PRG-RAM DMA access */ +/*--------------------------------------------------------------------------*/ +void prg_ram_dma_w(unsigned int words) +{ + uint16 data; + + /* CDC buffer source address */ + uint16 src_index = cdc.dac.w & 0x3ffe; + + /* PRG-RAM destination address*/ + uint32 dst_index = (scd.regs[0x0a>>1].w << 3) & 0x7fffe; + + /* update DMA destination address */ + scd.regs[0x0a>>1].w += (words >> 2); + + /* update DMA source address */ + cdc.dac.w += (words << 1); + + /* check PRG-RAM write protected area */ + if (dst_index < (scd.regs[0x02>>1].byte.h << 9)) + { + return; + } + + /* DMA transfer */ + while (words--) + { + /* read 16-bit word from CDC buffer */ + data = *(uint16 *)(cdc.ram + src_index); + +#ifdef LSB_FIRST + /* source data is stored in big endian format */ + data = ((data >> 8) | (data << 8)) & 0xffff; +#endif + + /* write 16-bit word to PRG-RAM */ + *(uint16 *)(scd.prg_ram + dst_index) = data ; + + /* increment CDC buffer source address */ + src_index = (src_index + 2) & 0x3ffe; + + /* increment PRG-RAM destination address */ + dst_index = (dst_index + 2) & 0x7fffe; + } +} + +/*--------------------------------------------------------------------------*/ +/* PRG-RAM write protected area */ +/*--------------------------------------------------------------------------*/ +static void prg_ram_write_byte(unsigned int address, unsigned int data) +{ + address &= 0x7ffff; + if (address >= (scd.regs[0x02>>1].byte.h << 9)) + { + WRITE_BYTE(scd.prg_ram, address, data); + return; + } +#ifdef LOGERROR + error("[SUB 68k] PRG-RAM protected write8 %08X = %02X (%08X)\n", address, data, s68k.pc); +#endif +} + +static void prg_ram_write_word(unsigned int address, unsigned int data) +{ + address &= 0x7fffe; + if (address >= (scd.regs[0x02>>1].byte.h << 9)) + { + *(uint16 *)(scd.prg_ram + address) = data; + return; + } +#ifdef LOGERROR + error("[SUB 68k] PRG-RAM protected write16 %08X = %02X (%08X)\n", address, data, s68k.pc); +#endif +} + +/*--------------------------------------------------------------------------*/ +/* internal backup RAM (8KB) */ +/*--------------------------------------------------------------------------*/ +static unsigned int bram_read_byte(unsigned int address) +{ + /* LSB only */ + if (address & 1) + { + return scd.bram[(address >> 1) & 0x1fff]; + } + + return 0xff; +} + +static unsigned int bram_read_word(unsigned int address) +{ + return (scd.bram[(address >> 1) & 0x1fff] | 0xff00); +} + +static void bram_write_byte(unsigned int address, unsigned int data) +{ + /* LSB only */ + if (address & 1) + { + scd.bram[(address >> 1) & 0x1fff] = data; + } +} + +static void bram_write_word(unsigned int address, unsigned int data) +{ + scd.bram[(address >> 1) & 0x1fff] = data & 0xff; +} + +/*--------------------------------------------------------------------------*/ +/* PCM chip & Gate-Array area */ +/*--------------------------------------------------------------------------*/ + +static void s68k_poll_detect(unsigned int reg_mask) +{ + /* detect SUB-CPU register polling */ + if (s68k.poll.detected & reg_mask) + { + if (s68k.cycles <= s68k.poll.cycle) + { + if (s68k.pc == s68k.poll.pc) + { + /* SUB-CPU polling confirmed ? */ + if (s68k.poll.detected & 1) + { + /* idle SUB-CPU until register is modified */ + s68k.cycles = s68k.cycle_end; + s68k.stopped = reg_mask; +#ifdef LOG_SCD + error("s68k stopped from %d cycles\n", s68k.cycles); +#endif + } + else + { + /* confirm SUB-CPU polling */ + s68k.poll.detected |= 1; + s68k.poll.cycle = s68k.cycles + 392; + } + } + return; + } + } + else + { + /* set SUB-CPU register access flag */ + s68k.poll.detected = reg_mask; + } + + /* reset SUB-CPU polling detection */ + s68k.poll.cycle = s68k.cycles + 392; + s68k.poll.pc = s68k.pc; +} + +static void s68k_poll_sync(unsigned int reg_mask) +{ + /* relative MAIN-CPU cycle counter */ + unsigned int cycles = (s68k.cycles * MCYCLES_PER_LINE) / SCYCLES_PER_LINE; + + /* sync MAIN-CPU with SUB-CPU */ + if (!m68k.stopped) + { + m68k_run(cycles); + } + + /* MAIN-CPU idle on register polling ? */ + if (m68k.stopped & reg_mask) + { + /* sync MAIN-CPU with SUB-CPU */ + m68k.cycles = cycles; + + /* restart MAIN-CPU */ + m68k.stopped = 0; +#ifdef LOG_SCD + error("m68k started from %d cycles\n", cycles); +#endif + } + + /* clear CPU register access flags */ + s68k.poll.detected &= ~reg_mask; + m68k.poll.detected &= ~reg_mask; +} + +static unsigned int scd_read_byte(unsigned int address) +{ + /* PCM area (8K) is mirrored into $FF0000-$FF7FFF */ + if (address < 0xff8000) + { + /* get /LDS only */ + if (address & 1) + { + return pcm_read((address >> 1) & 0x1fff); + } + + return s68k_read_bus_8(address); + } + +#ifdef LOG_SCD + error("[%d][%d]read byte CD register %X (%X)\n", v_counter, s68k.cycles, address, s68k.pc); +#endif + + /* Memory Mode */ + if (address == 0xff8003) + { + s68k_poll_detect(1<<0x03); + return scd.regs[0x03>>1].byte.l; + } + + /* MAIN-CPU communication flags */ + if (address == 0xff800e) + { + s68k_poll_detect(1<<0x0e); + return scd.regs[0x0e>>1].byte.h; + } + + /* CDC transfer status */ + if (address == 0xff8004) + { + s68k_poll_detect(1<<0x04); + return scd.regs[0x04>>1].byte.h; + } + + /* GFX operation status */ + if (address == 0xff8058) + { + s68k_poll_detect(1<<0x08); + return scd.regs[0x58>>1].byte.h; + } + + /* CDC register data (controlled by BIOS, byte access only ?) */ + if (address == 0xff8007) + { + unsigned int data = cdc_reg_r(); +#ifdef LOG_CDC + error("CDC register %X read 0x%02X (%X)\n", scd.regs[0x04>>1].byte.l & 0x0F, data, s68k.pc); +#endif + return data; + } + + /* LED status */ + if (address == 0xff8000) + { + /* register $00 is reserved for MAIN-CPU, we use $06 instead */ + return scd.regs[0x06>>1].byte.h; + } + + /* RESET status */ + if (address == 0xff8001) + { + /* always return 1 */ + return 0x01; + } + + /* Font data */ + if ((address >= 0xff8050) && (address <= 0xff8056)) + { + /* shifted 4-bit input (xxxx00) */ + uint8 bits = (scd.regs[0x4e>>1].w >> (((address & 6) ^ 6) << 1)) << 2; + + /* color code */ + uint8 code = scd.regs[0x4c>>1].byte.l; + + /* 16-bit font data (4 pixels = 16 bits) */ + uint16 data = (code >> (bits & 4)) & 0x0f; + + bits = bits >> 1; + data = data | (((code >> (bits & 4)) << 4) & 0xf0); + + bits = bits >> 1; + data = data | (((code >> (bits & 4)) << 8) & 0xf00); + + bits = bits >> 1; + data = data | (((code >> (bits & 4)) << 12) & 0xf000); + + return (address & 1) ? (data & 0xff) : (data >> 8); + } + + /* MAIN-CPU communication words */ + if ((address & 0x1f0) == 0x10) + { + s68k_poll_detect(1 << (address & 0x1f)); + } + + /* default registers */ + if (address & 1) + { + /* register LSB */ + return scd.regs[(address >> 1) & 0xff].byte.l; + } + + /* register MSB */ + return scd.regs[(address >> 1) & 0xff].byte.h; +} + +static unsigned int scd_read_word(unsigned int address) +{ + /* PCM area (8K) is mirrored into $FF0000-$FF7FFF */ + if (address < 0xff8000) + { + /* get /LDS only */ + return pcm_read((address >> 1) & 0x1fff); + } + +#ifdef LOG_SCD + error("[%d][%d]read word CD register %X (%X)\n", v_counter, s68k.cycles, address, s68k.pc); +#endif + + /* Memory Mode */ + if (address == 0xff8002) + { + s68k_poll_detect(1<<0x03); + return scd.regs[0x03>>1].w; + } + + /* CDC host data (word access only ?) */ + if (address == 0xff8008) + { + return cdc_host_r(); + } + + /* LED & RESET status */ + if (address == 0xff8000) + { + /* register $00 is reserved for MAIN-CPU, we use $06 instead */ + return scd.regs[0x06>>1].w; + } + + /* Stopwatch counter (word access only ?) */ + if (address == 0xff800c) + { + /* cycle-accurate counter value */ + return (scd.regs[0x0c>>1].w + ((s68k.cycles - scd.stopwatch) / TIMERS_SCYCLES_RATIO)) & 0xfff; + } + + /* Font data */ + if ((address >= 0xff8050) && (address <= 0xff8056)) + { + /* shifted 4-bit input (xxxx00) */ + uint8 bits = (scd.regs[0x4e>>1].w >> (((address & 6) ^ 6) << 1)) << 2; + + /* color code */ + uint8 code = scd.regs[0x4c>>1].byte.l; + + /* 16-bit font data (4 pixels = 16 bits) */ + uint16 data = (code >> (bits & 4)) & 0x0f; + + bits = bits >> 1; + data = data | (((code >> (bits & 4)) << 4) & 0xf0); + + bits = bits >> 1; + data = data | (((code >> (bits & 4)) << 8) & 0xf00); + + bits = bits >> 1; + data = data | (((code >> (bits & 4)) << 12) & 0xf000); + + return data; + } + + /* MAIN-CPU communication words */ + if ((address & 0x1f0) == 0x10) + { + if (!m68k.stopped) + { + /* relative MAIN-CPU cycle counter */ + unsigned int cycles = (s68k.cycles * MCYCLES_PER_LINE) / SCYCLES_PER_LINE; + + /* sync MAIN-CPU with SUB-CPU (Mighty Morphin Power Rangers) */ + m68k_run(cycles); + } + + s68k_poll_detect(3 << (address & 0x1e)); + } + + /* default registers */ + return scd.regs[(address >> 1) & 0xff].w; +} + +INLINE void word_ram_switch(uint8 mode) +{ + int i; + uint16 *ptr1 = (uint16 *)(scd.word_ram_2M); + uint16 *ptr2 = (uint16 *)(scd.word_ram[0]); + uint16 *ptr3 = (uint16 *)(scd.word_ram[1]); + + if (mode & 0x04) + { + /* 2M -> 1M mode */ + for (i=0; i<0x10000; i++) + { + *ptr2++=*ptr1++; + *ptr3++=*ptr1++; + } + } + else + { + /* 1M -> 2M mode */ + for (i=0; i<0x10000; i++) + { + *ptr1++=*ptr2++; + *ptr1++=*ptr3++; + } + + /* allow Word-RAM access from both CPU in 2M mode (fixes sync issues in Mortal Kombat) */ + for (i=scd.cartridge.boot+0x20; i> 1) & 0x1fff, data); + return; + } + + s68k_unused_8_w(address, data); + return; + } + +#ifdef LOG_SCD + error("[%d][%d]write byte CD register %X -> 0x%02x (%X)\n", v_counter, s68k.cycles, address, data, s68k.pc); +#endif + + /* Gate-Array registers */ + switch (address & 0x1ff) + { + case 0x00: /* LED status */ + { + /* register $00 is reserved for MAIN-CPU, use $06 instead */ + scd.regs[0x06 >> 1].byte.h = data; + return; + } + + case 0x01: /* RESET status */ + { + /* RESET bit cleared ? */ + if (!(data & 0x01)) + { + /* reset CD hardware */ + scd_reset(0); + } + return; + } + + case 0x03: /* Memory Mode */ + { + s68k_poll_sync(1<<0x03); + + /* detect MODE & RET bits modifications */ + if ((data ^ scd.regs[0x03 >> 1].byte.l) & 0x05) + { + int i; + + /* MODE bit */ + if (data & 0x04) + { + /* 2M->1M mode switch */ + if (!(scd.regs[0x03 >> 1].byte.l & 0x04)) + { + /* re-arrange Word-RAM banks */ + word_ram_switch(0x04); + } + + /* RET bit in 1M Mode */ + if (data & 0x01) + { + /* Word-RAM 1 assigned to MAIN-CPU */ + for (i=scd.cartridge.boot+0x20; i> 1].byte.l = (scd.regs[0x02 >> 1].byte.l & ~0x1f) | (data & 0x1d); + return; + } + else + { + /* 1M->2M mode switch */ + if (scd.regs[0x02 >> 1].byte.l & 0x04) + { + /* re-arrange Word-RAM banks */ + word_ram_switch(0x00); + + /* RET bit set during 1M mode ? */ + data |= ~scd.dmna & 0x01; + + /* check if RET bit is cleared */ + if (!(data & 0x01)) + { + /* set DMNA bit */ + data |= 0x02; + + /* mask BK0-1 bits (MAIN-CPU side only) */ + scd.regs[0x02 >> 1].byte.l = (scd.regs[0x02 >> 1].byte.l & ~0x1f) | (data & 0x1f); + return; + } + } + + /* RET bit set in 2M mode */ + if (data & 0x01) + { + /* Word-RAM is returned to MAIN-CPU */ + scd.dmna = 0; + + /* clear DMNA bit */ + scd.regs[0x02 >> 1].byte.l = (scd.regs[0x02 >> 1].byte.l & ~0x1f) | (data & 0x1d); + return; + } + } + } + + /* update PM0-1 & MODE bits */ + scd.regs[0x02 >> 1].byte.l = (scd.regs[0x02 >> 1].byte.l & ~0x1c) | (data & 0x1c); + return; + } + + case 0x07: /* CDC register write */ + { + cdc_reg_w(data); + return; + } + + case 0x0e: /* SUB-CPU communication flags */ + case 0x0f: /* !LWR is ignored (Space Ace, Dragon's Lair) */ + { + s68k_poll_sync(1<<0x0f); + scd.regs[0x0f>>1].byte.l = data; + return; + } + + case 0x31: /* Timer */ + { + /* reload timer (one timer clock = 384 CPU cycles) */ + scd.timer = data * TIMERS_SCYCLES_RATIO; + + /* only non-zero data starts timer, writing zero stops it */ + if (data) + { + /* adjust regarding current CPU cycle */ + scd.timer += (s68k.cycles - scd.cycles); + } + + scd.regs[0x30>>1].byte.l = data; + return; + } + + case 0x33: /* Interrupts */ + { + /* update register value before updating interrupts */ + scd.regs[0x32>>1].byte.l = data; + + /* update IEN2 flag */ + scd.regs[0x00].byte.h = (scd.regs[0x00].byte.h & 0x7f) | ((data & 0x04) << 5); + + /* clear level 1 interrupt if disabled ("Batman Returns" option menu) */ + scd.pending &= ~(data & 0x02); + + /* update IRQ level */ + s68k_update_irq((scd.pending & data) >> 1); + return; + } + + case 0x37: /* CDD control (controlled by BIOS, byte access only ?) */ + { + /* CDD communication started ? */ + if ((data & 0x04) && !(scd.regs[0x37>>1].byte.l & 0x04)) + { + /* reset CDD cycle counter */ + cdd.cycles = (scd.cycles - s68k.cycles) * 3; + + /* set pending interrupt level 4 */ + scd.pending |= (1 << 4); + + /* update IRQ level if interrupt is enabled */ + if (scd.regs[0x32>>1].byte.l & 0x10) + { + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + + scd.regs[0x37>>1].byte.l = data; + return; + } + + default: + { + /* SUB-CPU communication words */ + if ((address & 0xf0) == 0x20) + { + s68k_poll_sync(1 << ((address - 0x10) & 0x1f)); + } + + /* default registers */ + if (address & 1) + { + /* register LSB */ + scd.regs[(address >> 1) & 0xff].byte.l = data; + return; + } + + /* register MSB */ + scd.regs[(address >> 1) & 0xff].byte.h = data; + return; + } + } +} + +static void scd_write_word(unsigned int address, unsigned int data) +{ + /* PCM area (8K) is mirrored into $FF0000-$FF7FFF */ + if (address < 0xff8000) + { + /* get /LDS only */ + pcm_write((address >> 1) & 0x1fff, data); + return; + } + +#ifdef LOG_SCD + error("[%d][%d]write word CD register %X -> 0x%04x (%X)\n", v_counter, s68k.cycles, address, data, s68k.pc); +#endif + + /* Gate-Array registers */ + switch (address & 0x1fe) + { + case 0x00: /* LED status & RESET */ + { + /* only update LED status (register $00 is reserved for MAIN-CPU, use $06 instead) */ + scd.regs[0x06>>1].byte.h = data >> 8; + + /* RESET bit cleared ? */ + if (!(data & 0x01)) + { + /* reset CD hardware */ + scd_reset(0); + } + return; + } + + case 0x02: /* Memory Mode */ + { + s68k_poll_sync(1<<0x03); + + /* detect MODE & RET bits modifications */ + if ((data ^ scd.regs[0x03>>1].byte.l) & 0x05) + { + int i; + + /* MODE bit */ + if (data & 0x04) + { + /* 2M->1M mode switch */ + if (!(scd.regs[0x03 >> 1].byte.l & 0x04)) + { + /* re-arrange Word-RAM banks */ + word_ram_switch(0x04); + } + + /* RET bit in 1M Mode */ + if (data & 0x01) + { + /* Word-RAM 1 assigned to MAIN-CPU */ + for (i=scd.cartridge.boot+0x20; i>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0x1f) | (data & 0x1d); + return; + } + else + { + /* 1M->2M mode switch */ + if (scd.regs[0x03>>1].byte.l & 0x04) + { + /* re-arrange Word-RAM banks */ + word_ram_switch(0x00); + + /* RET bit set during 1M mode ? */ + data |= ~scd.dmna & 0x01; + + /* check if RET bit is cleared */ + if (!(data & 0x01)) + { + /* set DMNA bit */ + data |= 0x02; + + /* mask BK0-1 bits (MAIN-CPU side only) */ + scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0x1f) | (data & 0x1f); + return; + } + } + + /* RET bit set in 2M mode */ + if (data & 0x01) + { + /* Word-RAM is returned to MAIN-CPU */ + scd.dmna = 0; + + /* clear DMNA bit */ + scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0x1f) | (data & 0x1d); + return; + } + } + } + + /* update PM0-1 & MODE bits */ + scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0x1c) | (data & 0x1c); + return; + } + + case 0x06: /* CDC register write */ + { + cdc_reg_w(data); + return; + } + + case 0x0c: /* Stopwatch (word access only) */ + { + /* synchronize the counter with SUB-CPU */ + int ticks = (s68k.cycles - scd.stopwatch) / TIMERS_SCYCLES_RATIO; + scd.stopwatch += (ticks * TIMERS_SCYCLES_RATIO); + + /* any writes clear the counter */ + scd.regs[0x0c>>1].w = 0; + return; + } + + case 0x0e: /* CPU Communication flags */ + { + s68k_poll_sync(1<<0x0f); + + /* D8-D15 ignored -> only SUB-CPU flags are updated */ + scd.regs[0x0f>>1].byte.l = data & 0xff; + return; + } + + case 0x30: /* Timer */ + { + /* LSB only */ + data &= 0xff; + + /* reload timer (one timer clock = 384 CPU cycles) */ + scd.timer = data * TIMERS_SCYCLES_RATIO; + + /* only non-zero data starts timer, writing zero stops it */ + if (data) + { + /* adjust regarding current CPU cycle */ + scd.timer += (s68k.cycles - scd.cycles); + } + + scd.regs[0x30>>1].byte.l = data; + return; + } + + case 0x32: /* Interrupts */ + { + /* LSB only */ + data &= 0xff; + + /* update register value before updating interrupts */ + scd.regs[0x32>>1].byte.l = data; + + /* update IEN2 flag */ + scd.regs[0x00].byte.h = (scd.regs[0x00].byte.h & 0x7f) | ((data & 0x04) << 5); + + /* clear pending level 1 interrupt if disabled ("Batman Returns" option menu) */ + scd.pending &= ~(data & 0x02); + + /* update IRQ level */ + s68k_update_irq((scd.pending & data) >> 1); + return; + } + + case 0x4a: /* CDD command 9 (controlled by BIOS, word access only ?) */ + { + scd.regs[0x4a>>1].w = 0; + cdd_process(); +#ifdef LOG_CDD + error("CDD command: %02x %02x %02x %02x %02x %02x %02x %02x\n",scd.regs[0x42>>1].byte.h, scd.regs[0x42>>1].byte.l, scd.regs[0x44>>1].byte.h, scd.regs[0x44>>1].byte.l, scd.regs[0x46>>1].byte.h, scd.regs[0x46>>1].byte.l, scd.regs[0x48>>1].byte.h, scd.regs[0x48>>1].byte.l); + error("CDD status: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",scd.regs[0x38>>1].byte.h, scd.regs[0x38>>1].byte.l, scd.regs[0x3a>>1].byte.h, scd.regs[0x3a>>1].byte.l, scd.regs[0x3c>>1].byte.h, scd.regs[0x3c>>1].byte.l, scd.regs[0x3e>>1].byte.h, scd.regs[0x3e>>1].byte.l, scd.regs[0x40>>1].byte.h, scd.regs[0x40>>1].byte.l); +#endif + break; + } + + case 0x66: /* Trace vector base address */ + { + scd.regs[0x66>>1].w = data; + + /* start GFX operation */ + gfx_start(data, s68k.cycles); + return; + } + + default: + { + /* SUB-CPU communication words */ + if ((address & 0xf0) == 0x20) + { + s68k_poll_sync(3 << ((address - 0x10) & 0x1e)); + } + + /* default registers */ + scd.regs[(address >> 1) & 0xff].w = data; + return; + } + } +} + + +void scd_init(void) +{ + int i; + + /****************************************************************/ + /* MAIN-CPU low memory map ($000000-$7FFFFF) */ + /****************************************************************/ + + /* 0x00: boot from CD (Mode 2), 0x40: boot from cartridge (Mode 1) */ + uint8 base = scd.cartridge.boot; + + /* $400000-$7FFFFF (resp. $000000-$3FFFFF): cartridge area (4MB) */ + cd_cart_init(); + + /* $000000-$1FFFFF (resp. $400000-$5FFFFF): CD memory area */ + for (i=base; i>1].w = 0x0002; + scd.regs[0x02>>1].w = 0x0001; + + /* 2M mode */ + word_ram_switch(0); + + /* reset PRG-RAM banking on MAIN-CPU side */ + for (i=scd.cartridge.boot+0x02; i>1], 0, sizeof(scd.regs) - 4); + } + + /* SUB-CPU side default values */ + scd.regs[0x08>>1].w = 0xffff; + scd.regs[0x0a>>1].w = 0xffff; + scd.regs[0x36>>1].w = 0x0100; + scd.regs[0x40>>1].w = 0x000f; + scd.regs[0x42>>1].w = 0xffff; + scd.regs[0x44>>1].w = 0xffff; + scd.regs[0x46>>1].w = 0xffff; + scd.regs[0x48>>1].w = 0xffff; + scd.regs[0x4a>>1].w = 0xffff; + + /* RESET register always return 1 (register $06 is unused by both sides, it is used for SUB-CPU first register) */ + scd.regs[0x06>>1].byte.l = 0x01; + + /* Reset Timer & Stopwatch counters */ + scd.timer = 0; + scd.stopwatch = 0; + + /* Reset frame cycle counter */ + scd.cycles = 0; + + /* Clear pending interrupts */ + scd.pending = 0; + + /* Clear CPU polling detection */ + memset(&m68k.poll, 0, sizeof(m68k.poll)); + memset(&s68k.poll, 0, sizeof(s68k.poll)); + + /* Reset CD hardware */ + cdd_reset(); + cdc_reset(); + gfx_reset(); + pcm_reset(); +} + +void scd_update(unsigned int cycles) +{ + /* update CDC DMA transfer */ + if (cdc.dma_w) + { + cdc_dma_update(); + } + + /* run both CPU in sync until end of line */ + do + { + m68k_run(cycles); + s68k_run(scd.cycles + SCYCLES_PER_LINE); + } + while ((m68k.cycles < cycles) || (s68k.cycles < (scd.cycles + SCYCLES_PER_LINE))); + + /* increment CD hardware cycle counter */ + scd.cycles += SCYCLES_PER_LINE; + + /* CDD processing at 75Hz (one clock = 12500000/75 = 500000/3 CPU clocks) */ + cdd.cycles += (SCYCLES_PER_LINE * 3); + if (cdd.cycles >= (500000 * 4)) + { + /* reload CDD cycle counter */ + cdd.cycles -= (500000 * 4); + + /* update CDD sector */ + cdd_update(); + + /* check if a new CDD command has been processed */ + if (!(scd.regs[0x4a>>1].byte.l & 0xf0)) + { + /* reset CDD command wait flag */ + scd.regs[0x4a>>1].byte.l = 0xf0; + + /* pending level 4 interrupt */ + scd.pending |= (1 << 4); + + /* level 4 interrupt enabled */ + if (scd.regs[0x32>>1].byte.l & 0x10) + { + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + } + + /* Timer */ + if (scd.timer) + { + /* decrement timer */ + scd.timer -= SCYCLES_PER_LINE; + if (scd.timer <= 0) + { + /* reload timer (one timer clock = 384 CPU cycles) */ + scd.timer += (scd.regs[0x30>>1].byte.l * TIMERS_SCYCLES_RATIO); + + /* level 3 interrupt enabled ? */ + if (scd.regs[0x32>>1].byte.l & 0x08) + { + /* trigger level 3 interrupt */ + scd.pending |= (1 << 3); + + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + } + + /* GFX processing */ + if (scd.regs[0x58>>1].byte.h & 0x80) + { + /* update graphics operation if running */ + gfx_update(scd.cycles); + } +} + +void scd_end_frame(unsigned int cycles) +{ + /* run Stopwatch until end of frame */ + int ticks = (cycles - scd.stopwatch) / TIMERS_SCYCLES_RATIO; + scd.regs[0x0c>>1].w = (scd.regs[0x0c>>1].w + ticks) & 0xfff; + + /* adjust Stopwatch counter for next frame (can be negative) */ + scd.stopwatch += (ticks * TIMERS_SCYCLES_RATIO) - cycles; + + /* adjust SUB-CPU & GPU cycle counters for next frame */ + s68k.cycles -= cycles; + gfx.cycles -= cycles; + + /* reset CPU registers polling */ + m68k.poll.cycle = 0; + s68k.poll.cycle = 0; +} + +int scd_context_save(uint8 *state) +{ + uint16 tmp16; + uint32 tmp32; + int bufferptr = 0; + + /* internal harware */ + save_param(scd.regs, sizeof(scd.regs)); + save_param(&scd.cycles, sizeof(scd.cycles)); + save_param(&scd.timer, sizeof(scd.timer)); + save_param(&scd.pending, sizeof(scd.pending)); + save_param(&scd.dmna, sizeof(scd.dmna)); + + /* GFX processor */ + bufferptr += gfx_context_save(&state[bufferptr]); + + /* CD Data controller */ + bufferptr += cdc_context_save(&state[bufferptr]); + + /* CD Drive processor */ + bufferptr += cdd_context_save(&state[bufferptr]); + + /* PCM chip */ + bufferptr += pcm_context_save(&state[bufferptr]); + + /* PRG-RAM */ + save_param(scd.prg_ram, sizeof(scd.prg_ram)); + + /* Word-RAM */ + if (scd.regs[0x03>>1].byte.l & 0x04) + { + /* 1M mode */ + save_param(scd.word_ram, sizeof(scd.word_ram)); + } + else + { + /* 2M mode */ + save_param(scd.word_ram_2M, sizeof(scd.word_ram_2M)); + } + + /* MAIN-CPU & SUB-CPU polling */ + save_param(&m68k.poll, sizeof(m68k.poll)); + save_param(&s68k.poll, sizeof(s68k.poll)); + + /* H-INT default vector */ + tmp16 = *(uint16 *)(m68k.memory_map[0].base + 0x72); + save_param(&tmp16, 2); + + /* SUB-CPU internal state */ + save_param(&s68k.cycles, sizeof(s68k.cycles)); + save_param(&s68k.int_level, sizeof(s68k.int_level)); + save_param(&s68k.stopped, sizeof(s68k.stopped)); + + /* SUB-CPU registers */ + tmp32 = s68k_get_reg(M68K_REG_D0); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_D1); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_D2); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_D3); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_D4); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_D5); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_D6); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_D7); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_A0); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_A1); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_A2); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_A3); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_A4); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_A5); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_A6); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_A7); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_PC); save_param(&tmp32, 4); + tmp16 = s68k_get_reg(M68K_REG_SR); save_param(&tmp16, 2); + tmp32 = s68k_get_reg(M68K_REG_USP); save_param(&tmp32, 4); + tmp32 = s68k_get_reg(M68K_REG_ISP); save_param(&tmp32, 4); + + /* bootable MD cartridge */ + if (scd.cartridge.boot) + { + bufferptr += md_cart_context_save(&state[bufferptr]); + } + + return bufferptr; +} + +int scd_context_load(uint8 *state) +{ + int i; + uint16 tmp16; + uint32 tmp32; + int bufferptr = 0; + + /* internal harware */ + load_param(scd.regs, sizeof(scd.regs)); + load_param(&scd.cycles, sizeof(scd.cycles)); + load_param(&scd.timer, sizeof(scd.timer)); + load_param(&scd.pending, sizeof(scd.pending)); + load_param(&scd.dmna, sizeof(scd.dmna)); + + /* GFX processor */ + bufferptr += gfx_context_load(&state[bufferptr]); + + /* CD Data controller */ + bufferptr += cdc_context_load(&state[bufferptr]); + + /* CD Drive processor */ + bufferptr += cdd_context_load(&state[bufferptr]); + + /* PCM chip */ + bufferptr += pcm_context_load(&state[bufferptr]); + + /* PRG-RAM */ + load_param(scd.prg_ram, sizeof(scd.prg_ram)); + + /* PRG-RAM 128k bank mapped to $020000-$03FFFF (resp. $420000-$43FFFF) */ + m68k.memory_map[scd.cartridge.boot + 0x02].base = scd.prg_ram + ((scd.regs[0x03>>1].byte.l & 0xc0) << 11); + m68k.memory_map[scd.cartridge.boot + 0x03].base = m68k.memory_map[scd.cartridge.boot + 0x02].base + 0x10000; + + /* Word-RAM */ + if (scd.regs[0x03>>1].byte.l & 0x04) + { + /* 1M Mode */ + load_param(scd.word_ram, sizeof(scd.word_ram)); + + if (scd.regs[0x03>>1].byte.l & 0x01) + { + /* Word-RAM 1 assigned to MAIN-CPU */ + for (i=scd.cartridge.boot+0x20; i>1].byte.l) >> 1); + } + + return M68K_INT_ACK_AUTOVECTOR; +} diff --git a/genplus-gx/core/cd_hw/scd.h b/genplus-gx/core/cd_hw/scd.h new file mode 100644 index 0000000000..ba9a0a364d --- /dev/null +++ b/genplus-gx/core/cd_hw/scd.h @@ -0,0 +1,90 @@ +/*************************************************************************************** + * Genesis Plus + * Mega CD / Sega CD hardware + * + * Copyright (C) 2012-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ +#ifndef _HW_SCD_ +#define _HW_SCD_ + +#include "cdd.h" +#include "cdc.h" +#include "gfx.h" +#include "pcm.h" +#include "cd_cart.h" + +#define scd ext.cd_hw + +/* 5000000 SCD clocks/s = ~3184 clocks/line with a Master Clock of 53.693175 MHz */ +/* This would be slightly (~30 clocks) more on PAL systems because of the slower */ +/* Master Clock (53.203424 MHz) but not enough to really care about since clocks */ +/* are not running in sync anyway. */ +#define SCD_CLOCK 50000000 +#define SCYCLES_PER_LINE 3184 + +/* Timer & Stopwatch clocks divider */ +#define TIMERS_SCYCLES_RATIO (384 * 4) + +/* CD hardware */ +typedef struct +{ + cd_cart_t cartridge; /* ROM/RAM Cartridge */ + uint8 bootrom[0x20000]; /* 128K internal BOOT ROM */ + uint8 prg_ram[0x80000]; /* 512K PRG-RAM */ + uint8 word_ram[2][0x20000]; /* 2 x 128K Word RAM (1M mode) */ + uint8 word_ram_2M[0x40000]; /* 256K Word RAM (2M mode) */ + uint8 bram[0x2000]; /* 8K Backup RAM */ + reg16_t regs[0x100]; /* 256 x 16-bit ASIC registers */ + uint32 cycles; /* Master clock counter */ + int32 stopwatch; /* Stopwatch counter */ + int32 timer; /* Timer counter */ + uint8 pending; /* Pending interrupts */ + uint8 dmna; /* Pending DMNA write status */ + gfx_t gfx_hw; /* Graphics processor */ + cdc_t cdc_hw; /* CD data controller */ + cdd_t cdd_hw; /* CD drive processor */ + pcm_t pcm_hw; /* PCM chip */ +} cd_hw_t; + +/* Function prototypes */ +extern void scd_init(void); +extern void scd_reset(int hard); +extern void scd_update(unsigned int cycles); +extern void scd_end_frame(unsigned int cycles); +extern int scd_context_load(uint8 *state); +extern int scd_context_save(uint8 *state); +extern int scd_68k_irq_ack(int level); +extern void prg_ram_dma_w(unsigned int words); + +#endif diff --git a/genplus-gx/core/genesis.c b/genplus-gx/core/genesis.c new file mode 100644 index 0000000000..f15f2f7ff9 --- /dev/null +++ b/genplus-gx/core/genesis.c @@ -0,0 +1,540 @@ +/*************************************************************************************** + * Genesis Plus + * Internal Hardware & Bus controllers + * + * Support for SG-1000, Mark-III, Master System, Game Gear, Mega Drive & Mega CD hardware + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +external_t ext; /* External Hardware (Cartridge, CD unit, ...) */ +uint8 boot_rom[0x800]; /* Genesis BOOT ROM */ +uint8 work_ram[0x10000]; /* 68K RAM */ +uint8 zram[0x2000]; /* Z80 RAM */ +uint32 zbank; /* Z80 bank window address */ +uint8 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */ +uint8 pico_current; /* PICO current page */ + +static uint8 tmss[4]; /* TMSS security register */ + +/*--------------------------------------------------------------------------*/ +/* Init, reset, shutdown functions */ +/*--------------------------------------------------------------------------*/ + +void gen_init(void) +{ + int i; + + /* initialize Z80 */ + z80_init(0,z80_irq_callback); + + /* 8-bit / 16-bit modes */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* initialize main 68k */ + m68k_init(); + m68k.aerr_enabled = config.addr_error; + + /* initialize main 68k memory map */ + + /* $800000-$DFFFFF : illegal access by default */ + for (i=0x80; i<0xe0; i++) + { + m68k.memory_map[i].base = work_ram; /* for VDP DMA */ + m68k.memory_map[i].read8 = m68k_lockup_r_8; + m68k.memory_map[i].read16 = m68k_lockup_r_16; + m68k.memory_map[i].write8 = m68k_lockup_w_8; + m68k.memory_map[i].write16 = m68k_lockup_w_16; + zbank_memory_map[i].read = zbank_lockup_r; + zbank_memory_map[i].write = zbank_lockup_w; + } + + /* $C0xxxx, $C8xxxx, $D0xxxx, $D8xxxx : VDP ports */ + for (i=0xc0; i<0xe0; i+=8) + { + m68k.memory_map[i].read8 = vdp_read_byte; + m68k.memory_map[i].read16 = vdp_read_word; + m68k.memory_map[i].write8 = vdp_write_byte; + m68k.memory_map[i].write16 = vdp_write_word; + zbank_memory_map[i].read = zbank_read_vdp; + zbank_memory_map[i].write = zbank_write_vdp; + } + + /* $E00000-$FFFFFF : Work RAM (64k) */ + for (i=0xe0; i<0x100; i++) + { + m68k.memory_map[i].base = work_ram; + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + m68k.memory_map[i].write8 = NULL; + m68k.memory_map[i].write16 = NULL; + + /* Z80 can ONLY write to 68k RAM, not read it */ + zbank_memory_map[i].read = zbank_unused_r; + zbank_memory_map[i].write = NULL; + } + + if (system_hw == SYSTEM_PICO) + { + /* additional registers mapped to $800000-$80FFFF */ + m68k.memory_map[0x80].read8 = pico_read_byte; + m68k.memory_map[0x80].read16 = pico_read_word; + m68k.memory_map[0x80].write8 = m68k_unused_8_w; + m68k.memory_map[0x80].write16 = m68k_unused_16_w; + + /* there is no I/O area (Notaz) */ + m68k.memory_map[0xa1].read8 = m68k_read_bus_8; + m68k.memory_map[0xa1].read16 = m68k_read_bus_16; + m68k.memory_map[0xa1].write8 = m68k_unused_8_w; + m68k.memory_map[0xa1].write16 = m68k_unused_16_w; + + /* initialize page index (closed) */ + pico_current = 0; + } + else + { + /* $A10000-$A1FFFF : I/O & Control registers */ + m68k.memory_map[0xa1].read8 = ctrl_io_read_byte; + m68k.memory_map[0xa1].read16 = ctrl_io_read_word; + m68k.memory_map[0xa1].write8 = ctrl_io_write_byte; + m68k.memory_map[0xa1].write16 = ctrl_io_write_word; + zbank_memory_map[0xa1].read = zbank_read_ctrl_io; + zbank_memory_map[0xa1].write = zbank_write_ctrl_io; + + /* initialize Z80 memory map */ + /* $0000-$3FFF is mapped to Z80 RAM (8K mirrored) */ + /* $4000-$FFFF is mapped to hardware but Z80 PC should never point there */ + for (i=0; i<64; i++) + { + z80_readmap[i] = &zram[(i & 7) << 10]; + } + + /* initialize Z80 memory handlers */ + z80_writemem = z80_memory_w; + z80_readmem = z80_memory_r; + + /* initialize Z80 port handlers */ + z80_writeport = z80_unused_port_w; + z80_readport = z80_unused_port_r; + } + + /* $000000-$7FFFFF : external hardware area */ + if (system_hw == SYSTEM_MCD) + { + /* initialize SUB-CPU */ + s68k_init(); + + /* initialize CD hardware */ + scd_init(); + } + else + { + /* Cartridge hardware */ + md_cart_init(); + } + } + else + { + /* initialize cartridge hardware & Z80 memory handlers */ + sms_cart_init(); + + /* initialize Z80 ports handlers */ + switch (system_hw) + { + /* Master System compatibility mode */ + case SYSTEM_PBC: + { + z80_writeport = z80_md_port_w; + z80_readport = z80_md_port_r; + break; + } + + /* Game Gear hardware */ + case SYSTEM_GG: + case SYSTEM_GGMS: + { + /* initialize cartridge hardware & Z80 memory handlers */ + sms_cart_init(); + + /* initialize Z80 ports handlers */ + z80_writeport = z80_gg_port_w; + z80_readport = z80_gg_port_r; + break; + } + + /* Master SYstem hardware */ + case SYSTEM_SMS: + case SYSTEM_SMS2: + { + z80_writeport = z80_ms_port_w; + z80_readport = z80_ms_port_r; + break; + } + + /* Mark-III hardware */ + case SYSTEM_MARKIII: + { + z80_writeport = z80_m3_port_w; + z80_readport = z80_m3_port_r; + break; + } + + /* SG-1000 hardware */ + case SYSTEM_SG: + { + z80_writeport = z80_sg_port_w; + z80_readport = z80_sg_port_r; + break; + } + } + } +} + +void gen_reset(int hard_reset) +{ + /* System Reset */ + if (hard_reset) + { + /* clear RAM (TODO: use random bit patterns for all systems, like on real hardware) */ + memset(work_ram, 0x00, sizeof (work_ram)); + memset(zram, 0x00, sizeof (zram)); + } + else + { + /* reset YM2612 (on hard reset, this is done by sound_reset) */ + fm_reset(0); + } + + /* 68k & Z80 could be anywhere in VDP frame (Bonkers, Eternal Champions, X-Men 2) */ + m68k.cycles = Z80.cycles = (uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX)); + + /* 68k cycles should be a multiple of 7 */ + m68k.cycles = (m68k.cycles / 7) * 7; + + /* Z80 cycles should be a multiple of 15 */ + Z80.cycles = (Z80.cycles / 15) * 15; + + /* 8-bit / 16-bit modes */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + if (system_hw == SYSTEM_MCD) + { + /* FRES is only asserted on Power ON */ + if (hard_reset) + { + /* reset CD hardware */ + scd_reset(1); + } + } + + /* reset MD cartridge hardware */ + md_cart_reset(hard_reset); + + /* Z80 bus is released & Z80 is reseted */ + m68k.memory_map[0xa0].read8 = m68k_read_bus_8; + m68k.memory_map[0xa0].read16 = m68k_read_bus_16; + m68k.memory_map[0xa0].write8 = m68k_unused_8_w; + m68k.memory_map[0xa0].write16 = m68k_unused_16_w; + zstate = 0; + + /* assume default bank is $000000-$007FFF */ + zbank = 0; + + /* TMSS support */ + if ((config.bios & 1) && (system_hw == SYSTEM_MD) && hard_reset) + { + int i; + + /* clear TMSS register */ + memset(tmss, 0x00, sizeof(tmss)); + + /* VDP access is locked by default */ + for (i=0xc0; i<0xe0; i+=8) + { + m68k.memory_map[i].read8 = m68k_lockup_r_8; + m68k.memory_map[i].read16 = m68k_lockup_r_16; + m68k.memory_map[i].write8 = m68k_lockup_w_8; + m68k.memory_map[i].write16 = m68k_lockup_w_16; + zbank_memory_map[i].read = zbank_lockup_r; + zbank_memory_map[i].write = zbank_lockup_w; + } + + /* check if BOOT ROM is loaded */ + if (system_bios & SYSTEM_MD) + { + /* save default cartridge slot mapping */ + cart.base = m68k.memory_map[0].base; + + /* BOOT ROM is mapped at $000000-$0007FF */ + m68k.memory_map[0].base = boot_rom; + } + } + + /* reset MAIN-CPU */ + m68k_pulse_reset(); + } + else + { + /* RAM state at power-on is undefined on some systems */ + if ((system_hw == SYSTEM_MARKIII) || ((system_hw & SYSTEM_SMS) && (region_code == REGION_JAPAN_NTSC))) + { + /* some korean games rely on RAM to be initialized with values different from $00 or $ff */ + memset(work_ram, 0xf0, sizeof(work_ram)); + } + + /* reset cartridge hardware */ + sms_cart_reset(); + + /* halt 68k (/VRES is forced low) */ + m68k_pulse_halt(); + } + + /* reset Z80 */ + z80_reset(); + + /* some Z80 registers need to be initialized on Power ON */ + if (hard_reset) + { + /* Power Base Converter specific */ + if (system_hw == SYSTEM_PBC) + { + /* startup code logic (verified on real hardware): */ + /* 21 01 E1 : LD HL, $E101 + 25 -- -- : DEC H + F9 -- -- : LD SP,HL + C7 -- -- : RST $00 + 01 01 -- : LD BC, $xx01 + */ + Z80.hl.w.l = 0xE001; + Z80.sp.w.l = 0xDFFF; + Z80.r = 4; + } + + /* Master System specific (when BIOS is disabled) */ + else if ((system_hw & SYSTEM_SMS) && (!(config.bios & 1) || !(system_bios & SYSTEM_SMS))) + { + /* usually done by BIOS & required by some SMS games that don't initialize SP */ + Z80.sp.w.l = 0xDFFF; + } + } +} + +/*-----------------------------------------------------------------------*/ +/* OS ROM / TMSS register control functions (Genesis mode) */ +/*-----------------------------------------------------------------------*/ + +void gen_tmss_w(unsigned int offset, unsigned int data) +{ + int i; + + /* write TMSS register */ + WRITE_WORD(tmss, offset, data); + + /* VDP requires "SEGA" value to be written in TMSS register */ + if (memcmp((char *)tmss, "SEGA", 4) == 0) + { + for (i=0xc0; i<0xe0; i+=8) + { + m68k.memory_map[i].read8 = vdp_read_byte; + m68k.memory_map[i].read16 = vdp_read_word; + m68k.memory_map[i].write8 = vdp_write_byte; + m68k.memory_map[i].write16 = vdp_write_word; + zbank_memory_map[i].read = zbank_read_vdp; + zbank_memory_map[i].write = zbank_write_vdp; + } + } + else + { + for (i=0xc0; i<0xe0; i+=8) + { + m68k.memory_map[i].read8 = m68k_lockup_r_8; + m68k.memory_map[i].read16 = m68k_lockup_r_16; + m68k.memory_map[i].write8 = m68k_lockup_w_8; + m68k.memory_map[i].write16 = m68k_lockup_w_16; + zbank_memory_map[i].read = zbank_lockup_r; + zbank_memory_map[i].write = zbank_lockup_w; + } + } +} + +void gen_bankswitch_w(unsigned int data) +{ + /* check if BOOT ROM is loaded */ + if (system_bios & SYSTEM_MD) + { + if (data & 1) + { + /* enable cartridge ROM */ + m68k.memory_map[0].base = cart.base; + } + else + { + /* enable internal BOOT ROM */ + m68k.memory_map[0].base = boot_rom; + } + } +} + +unsigned int gen_bankswitch_r(void) +{ + /* check if BOOT ROM is loaded */ + if (system_bios & SYSTEM_MD) + { + return (m68k.memory_map[0].base == cart.base); + } + + return 0xff; +} + + +/*-----------------------------------------------------------------------*/ +/* Z80 Bus controller chip functions (Genesis mode) */ +/* ----------------------------------------------------------------------*/ + +void gen_zbusreq_w(unsigned int data, unsigned int cycles) +{ + if (data) /* !ZBUSREQ asserted */ + { + /* check if Z80 is going to be stopped */ + if (zstate == 1) + { + /* resynchronize with 68k */ + z80_run(cycles); + + /* enable 68k access to Z80 bus */ + m68k.memory_map[0xa0].read8 = z80_read_byte; + m68k.memory_map[0xa0].read16 = z80_read_word; + m68k.memory_map[0xa0].write8 = z80_write_byte; + m68k.memory_map[0xa0].write16 = z80_write_word; + } + + /* update Z80 bus status */ + zstate |= 2; + } + else /* !ZBUSREQ released */ + { + /* check if Z80 is going to be restarted */ + if (zstate == 3) + { + /* resynchronize with 68k */ + Z80.cycles = cycles; + + /* disable 68k access to Z80 bus */ + m68k.memory_map[0xa0].read8 = m68k_read_bus_8; + m68k.memory_map[0xa0].read16 = m68k_read_bus_16; + m68k.memory_map[0xa0].write8 = m68k_unused_8_w; + m68k.memory_map[0xa0].write16 = m68k_unused_16_w; + } + + /* update Z80 bus status */ + zstate &= 1; + } +} + +void gen_zreset_w(unsigned int data, unsigned int cycles) +{ + if (data) /* !ZRESET released */ + { + /* check if Z80 is going to be restarted */ + if (zstate == 0) + { + /* resynchronize with 68k */ + Z80.cycles = cycles; + + /* reset Z80 & YM2612 */ + z80_reset(); + fm_reset(cycles); + } + + /* check if 68k access to Z80 bus is granted */ + else if (zstate == 2) + { + /* enable 68k access to Z80 bus */ + m68k.memory_map[0xa0].read8 = z80_read_byte; + m68k.memory_map[0xa0].read16 = z80_read_word; + m68k.memory_map[0xa0].write8 = z80_write_byte; + m68k.memory_map[0xa0].write16 = z80_write_word; + + /* reset Z80 & YM2612 */ + z80_reset(); + fm_reset(cycles); + } + + /* update Z80 bus status */ + zstate |= 1; + } + else /* !ZRESET asserted */ + { + /* check if Z80 is going to be stopped */ + if (zstate == 1) + { + /* resynchronize with 68k */ + z80_run(cycles); + } + + /* check if 68k had access to Z80 bus */ + else if (zstate == 3) + { + /* disable 68k access to Z80 bus */ + m68k.memory_map[0xa0].read8 = m68k_read_bus_8; + m68k.memory_map[0xa0].read16 = m68k_read_bus_16; + m68k.memory_map[0xa0].write8 = m68k_unused_8_w; + m68k.memory_map[0xa0].write16 = m68k_unused_16_w; + } + + /* stop YM2612 */ + fm_reset(cycles); + + /* update Z80 bus status */ + zstate &= 2; + } +} + +void gen_zbank_w (unsigned int data) +{ + zbank = ((zbank >> 1) | ((data & 1) << 23)) & 0xFF8000; +} + + +/*-----------------------------------------------------------------------*/ +/* Z80 interrupt callback */ +/* ----------------------------------------------------------------------*/ + +int z80_irq_callback (int param) +{ + return -1; +} diff --git a/genplus-gx/core/genesis.h b/genplus-gx/core/genesis.h new file mode 100644 index 0000000000..a7b10a7300 --- /dev/null +++ b/genplus-gx/core/genesis.h @@ -0,0 +1,77 @@ +/*************************************************************************************** + * Genesis Plus + * Internal hardware & Bus controllers + * + * Support for SG-1000, Mark-III, Master System, Game Gear, Mega Drive & Mega CD hardware + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _GENESIS_H_ +#define _GENESIS_H_ + +#include "md_cart.h" +#include "sms_cart.h" +#include "scd.h" + +/* External Hardware */ +typedef union +{ + md_cart_t md_cart; + cd_hw_t cd_hw; +} external_t; + +/* Global variables */ +extern external_t ext; +extern uint8 boot_rom[0x800]; +extern uint8 work_ram[0x10000]; +extern uint8 zram[0x2000]; +extern uint32 zbank; +extern uint8 zstate; +extern uint8 pico_current; + +/* Function prototypes */ +extern void gen_init(void); +extern void gen_reset(int hard_reset); +extern void gen_tmss_w(unsigned int offset, unsigned int data); +extern void gen_bankswitch_w(unsigned int data); +extern unsigned int gen_bankswitch_r(void); +extern void gen_zbusreq_w(unsigned int state, unsigned int cycles); +extern void gen_zreset_w(unsigned int state, unsigned int cycles); +extern void gen_zbank_w(unsigned int state); +extern int z80_irq_callback(int param); + +#endif /* _GEN_H_ */ + diff --git a/genplus-gx/core/hvc.h b/genplus-gx/core/hvc.h new file mode 100644 index 0000000000..85e9d025c8 --- /dev/null +++ b/genplus-gx/core/hvc.h @@ -0,0 +1,652 @@ +/*************************************************************************************** + * Genesis Plus + * HV Counters + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +/* + NTSC, 256x192 + ------------- + + Lines Description + + 192 Active display + 24 Bottom border + 3 Bottom blanking + 3 Vertical blanking + 13 Top blanking + 27 Top border + + V counter values + 00-DA, D5-FF + + NTSC, 256x224 + ------------- + + Lines Description + + 224 Active display + 8 Bottom border + 3 Bottom blanking + 3 Vertical blanking + 13 Top blanking + 11 Top border + + V counter values + 00-EA, E5-FF + + NTSC, 256x240 + ------------- + + This mode does not work on NTSC machines. All 30 rows of the name table are + displayed, there is no border, blanking, or retrace period, and the next + frame starts after the 30th row. The display rolls continuously though it + can be stabilized by adjusting the vertical hold. + + V counter values + 00-FF, 00-06 + + PAL, 256x192 + ------------ + + Lines Description + + 192 Active display + 48 Bottom border + 3 Bottom blanking + 3 Vertical blanking + 13 Top blanking + 54 Top border + + V counter values + 00-F2, BA-FF + + PAL, 256x224 + ------------ + + Lines Description + + 224 Active display + 32 Bottom border + 3 Bottom blanking + 3 Vertical blanking + 13 Top blanking + 38 Top border + + V counter values + 00-FF, 00-02, CA-FF + + PAL, 256x240 + ------------ + + Lines Description + + 240 Active display + 24 Bottom border + 3 Bottom blanking + 3 Vertical blanking + 13 Top blanking + 30 Top border + + V counter values + 00-FF, 00-0A, D2-FF + + Here are some details about what the different screen areas look like, + useful if you are emulating overscan or if you want to have a 'virtual' + vertical hold control in your emulator. + + Active display - Where the display generated by the VDP goes. + Bottom border - Filled with border color from VDP register #7. + Bottom blanking - Filled with a light black color. (like display was blanked) + Vertical sync - Filled with a pure black color. (like display was turned off) + Top blanking - Filled with a light black color. (like display was blanked) + Top border - Filled with the border color from VDP register #7. + +*/ +#ifndef _HVC_H_ +#define _HVC_H_ + +/***************************************************************/ +/* */ +/* H-counter timings in H32 & H40 modes (starts from HINT) */ +/* */ +/* There are normally 3420 Master Clock counts per raster line */ +/* with 342 dots/line in H32 mode & 420 dots/line in H40 mode. */ +/* */ +/* in H32 mode, dot clock is divided from MCLK (MCLK/10) */ +/* in H40 mode, dot clock is divided from EDCLK (EDCLK/2) */ +/* */ +/* EDCLK (external dot clock ?) is generated outside the VDP: */ +/* When HSYNC is low, EDCLK varies between MCLK/10 and MCLK/8, */ +/* otherwise it is fixed to MCLK/8. */ +/* */ +/* Notes: */ +/* (1) VDP register 12 bit 7 enables use of EDCLK when set */ +/* (2) VDP register 12 bit 5 forces HSYNC high when set */ +/* (3) H32 or H40 mode is selected with VDP register $0C bit 0 */ +/* and can be set independently from above settings */ +/* */ +/* On real hardware, non-standard timings can be obtained by */ +/* modifying those settings (for example, dot clock can be set */ +/* to MCLK/8 in both modes if HSYNC output is disabled and if */ +/* EDCLK input is enabled in H32 mode / disabled in H40 mode), */ +/* resulting in slightly different H-counter and VDP timings. */ +/* */ +/* Genesis Plus GX timings always assume standard settings i.e */ +/* HSYNC output always enabled and EDCLK input enabled in H40 */ +/* mode / disabled in H32 mode. */ +/* */ +/***************************************************************/ + +static const uint8 cycle2hc32[3420] = +{ + /* end of active display (14 pixels -> 140 Mcycles) , H interrupt triggered, Vcounter increment */ + 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, + 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, + 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, + 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, + 0x89, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, + 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, + 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, + + /* right border (14 pixels -> 140 Mcycles) */ + 0x8c, 0x8c, 0x8c, 0x8c, + 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, + 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, + 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, + 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, + 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, + 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, + 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, + + /* right blanking (9 pixels -> 90 Mcycles), VDP status HBLANK flag set */ + 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0xe9, 0xe9, 0xe9, 0xe9, + 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, + 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, + 0xea, 0xea, 0xea, 0xea, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, + 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, + 0xec, 0xec, + + /* horizontal sync (26 pixels -> 260 Mcycles) */ + 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, + 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, + 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, + 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, + 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, + 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, + 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, + 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, + 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, + 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, + + /* left blanking (24 pixels -> 240 Mcycles) */ + 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, + 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, + 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, + 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, + 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 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, + /* V interrupt triggered (MD mode) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + + /* left border (13 pixels -> 130 Mcycles) , VDP status HBLANK flag cleared */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + + /* remaining active display (252 pixels -> 2520 Mcycles) */ + + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, + 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, + 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, + 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, + 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, + 0x1a, 0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, + 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, + 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d, + 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, + 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, + 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, + 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, + 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, + 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, + 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, + 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, + 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, + 0x3a, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, + 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3d, + 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, + 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, + 0x3e, 0x3e, 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, + 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, + 0x42, 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, + 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x45, 0x45, 0x45, + 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, + 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, + 0x46, 0x46, 0x46, 0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, + 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, + 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, + 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, + 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, + 0x4a, 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, + 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, + 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, 0x4d, + 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, + 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, + 0x4e, 0x4e, 0x4e, 0x4e, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, + 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, + 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51, 0x51, + 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, + 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, + 0x52, 0x52, 0x52, 0x52, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, + 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, + 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, + 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, + 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, + 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, + 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5d, + 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, + 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, + 0x5e, 0x5e, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, + 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, + 0x62, 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, + 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x65, + 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, + 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, + 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, + 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, + 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, + 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, + 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, + 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, + 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, + 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, + 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, + 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, + 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, + 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, + 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, + 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, + 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, + 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84 +}; + +static const uint8 cycle2hc40[3420] = +{ + /* end of active display (16 pixels -> 128 Mcycles) , HINT triggered , Vcounter increment */ + 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, + 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, + 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, + 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, + 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, + + /* right border (14 pixels -> 112 Mcycles) */ + 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, + 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, + 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, + 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, + 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, + 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, + 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, + + /* right blanking (9 pixels -> 72 Mcycles) , VDP status HBLANK flag set */ + 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, + 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, + 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, + 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, + 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, + + /* horizontal sync (32 pixels -> 313 Mcycles) */ + 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, + 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, + 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, + 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, + 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xea, 0xea, 0xea, + 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xeb, + 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, + 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, + 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, + 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, + 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, + 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, + 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, + 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, + 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, + 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, + 0xf6, + + /* left blanking (32 pixels -> 259 Mcycles) */ + 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, + 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, + 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, + 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, + 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, + 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + /* Vertical Interrupt triggered */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, + + /* left border (13 pixels -> 104 Mcycles) , VDP status HBLANK flag cleared */ + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + + /* remaining active display (304 pixels -> 2432 Mcycles) */ + 0x0d, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, + 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, + 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, + 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1a, 0x1a, 0x1a, 0x1a, + 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1b, + 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1c, 0x1c, + 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d, + 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, + 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26, 0x26, + 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2c, + 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, + 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x37, + 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x38, 0x38, 0x38, 0x38, + 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x3a, 0x3a, 0x3a, 0x3a, + 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x3c, + 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3d, + 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3e, 0x3e, 0x3e, 0x3e, + 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, + 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x43, + 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x45, 0x45, 0x45, + 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, 0x46, 0x46, 0x46, + 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x47, 0x47, 0x47, 0x47, + 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x48, 0x48, 0x48, 0x48, + 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, + 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4a, + 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4b, + 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4c, + 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, 0x4d, + 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4e, 0x4e, 0x4e, 0x4e, + 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4f, 0x4f, 0x4f, 0x4f, + 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x50, 0x50, 0x50, 0x50, + 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51, 0x51, + 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52, 0x52, 0x52, + 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x53, 0x53, 0x53, 0x53, + 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54, 0x54, 0x54, 0x54, + 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x58, + 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5a, + 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5b, + 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5d, + 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5e, 0x5e, + 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x5f, + 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x62, + 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x64, 0x64, 0x64, 0x64, + 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x65, + 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x67, + 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, + 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, + 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, + 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6e, + 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, + 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, + 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x73, + 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, + 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, + 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, + 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, + 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, + 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, + 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, + 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, + 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x86, + 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x87, 0x87, 0x87, 0x87, + 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x89, 0x89, 0x89, 0x89, + 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8a, + 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8b, + 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8c, + 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8d, + 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, + 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, + 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91, + 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x92, + 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, + 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94, + 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x95, 0x95, 0x95, 0x95, + 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x96, 0x96, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x97, + 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, 0x98, + 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9a, + 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, + 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9c, + 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, + 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9e, + 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9f, 0x9f, 0x9f, 0x9f, + 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0xa0, 0xa0, 0xa0, 0xa0, + 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1, + 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa2, + 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, + 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4}; + +#endif /* _HVC_H_ */ + diff --git a/genplus-gx/core/input_hw/activator.c b/genplus-gx/core/input_hw/activator.c new file mode 100644 index 0000000000..e2566356b6 --- /dev/null +++ b/genplus-gx/core/input_hw/activator.c @@ -0,0 +1,134 @@ +/*************************************************************************************** + * Genesis Plus + * Sega Activator support + * + * Copyright (C) 2011-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +static struct +{ + uint8 State; + uint8 Counter; +} activator[2]; + +void activator_reset(int index) +{ + + activator[index].State = 0x40; + activator[index].Counter = 0; +} + +INLINE unsigned char activator_read(int index) +{ + /* IR sensors 1-16 data (active low) */ + uint16 data = ~input.pad[index << 2]; + + /* D1 = D0 (data is ready) */ + uint8 temp = (activator[index].State & 0x01) << 1; + + switch (activator[index].Counter) + { + case 0: /* x x x x 0 1 0 0 */ + temp |= 0x04; + break; + + case 1: /* x x l1 l2 l3 l4 1 1 */ + temp |= ((data << 2) & 0x3C); + break; + + case 2: /* x x l5 l6 l7 l8 0 0 */ + temp |= ((data >> 2) & 0x3C); + break; + + case 3: /* x x h1 h2 h3 h4 1 1 */ + temp |= ((data >> 6) & 0x3C); + break; + + case 4: /* x x h5 h6 h7 h8 0 0 */ + temp |= ((data >> 10) & 0x3C); + break; + } + + return temp; +} + +INLINE void activator_write(int index, unsigned char data, unsigned char mask) +{ + /* update bits set as output only */ + data = (activator[index].State & ~mask) | (data & mask); + + /* TH transitions */ + if ((activator[index].State ^ data) & 0x40) + { + /* reset sequence cycle */ + activator[index].Counter = 0; + } + else + { + /* D0 transitions */ + if ((activator[index].State ^ data) & 0x01) + { + /* increment sequence cycle */ + if (activator[index].Counter < 4) + { + activator[index].Counter++; + } + } + } + + /* update internal state */ + activator[index].State = data; +} + +unsigned char activator_1_read(void) +{ + return activator_read(0); +} + +unsigned char activator_2_read(void) +{ + return activator_read(1); +} + +void activator_1_write(unsigned char data, unsigned char mask) +{ + activator_write(0, data, mask); +} + +void activator_2_write(unsigned char data, unsigned char mask) +{ + activator_write(1, data, mask); +} diff --git a/genplus-gx/core/input_hw/activator.h b/genplus-gx/core/input_hw/activator.h new file mode 100644 index 0000000000..18c18fee24 --- /dev/null +++ b/genplus-gx/core/input_hw/activator.h @@ -0,0 +1,49 @@ +/*************************************************************************************** + * Genesis Plus + * Sega Activator support + * + * Copyright (C) 2011-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _ACTIVATOR_H_ +#define _ACTIVATOR_H_ + +/* Function prototypes */ +extern void activator_reset(int index); +extern unsigned char activator_1_read(void); +extern unsigned char activator_2_read(void); +extern void activator_1_write(unsigned char data, unsigned char mask); +extern void activator_2_write(unsigned char data, unsigned char mask); + +#endif diff --git a/genplus-gx/core/input_hw/gamepad.c b/genplus-gx/core/input_hw/gamepad.c new file mode 100644 index 0000000000..a523b302d1 --- /dev/null +++ b/genplus-gx/core/input_hw/gamepad.c @@ -0,0 +1,241 @@ +/*************************************************************************************** + * Genesis Plus + * 3-Buttons & 6-Buttons pad support + * Support for J-CART & 4-Way Play adapters + * + * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "gamepad.h" + +static struct +{ + uint8 State; + uint8 Counter; + uint8 Timeout; +} gamepad[MAX_DEVICES]; + +static uint8 pad_index; + + +void gamepad_reset(int port) +{ + /* default state (Gouketsuji Ichizoku / Power Instinct, Samurai Spirits / Samurai Shodown) */ + gamepad[port].State = 0x40; + gamepad[port].Counter = 0; + gamepad[port].Timeout = 0; + + /* reset pad index (4-WayPlay) */ + pad_index = 0; +} + +void gamepad_refresh(int port) +{ + /* 6-buttons pad */ + if (gamepad[port].Timeout++ > 25) + { + gamepad[port].Counter = 0; + gamepad[port].Timeout = 0; + } +} + +INLINE unsigned char gamepad_read(int port) +{ + /* bit 7 is latched, returns current TH state */ + unsigned int data = (gamepad[port].State & 0x40) | 0x3F; + + /* pad value */ + unsigned int val = input.pad[port]; + + /* get current step (TH state) */ + unsigned int step = gamepad[port].Counter | ((data >> 6) & 1); + + switch (step) + { + case 1: /*** First High ***/ + case 3: /*** Second High ***/ + case 5: /*** Third High ***/ + { + /* TH = 1 : ?1CBRLDU */ + data &= ~(val & 0x3F); + break; + } + + case 0: /*** First low ***/ + case 2: /*** Second low ***/ + { + /* TH = 0 : ?0SA00DU */ + data &= ~(val & 0x03); + data &= ~((val >> 2) & 0x30); + data &= ~0x0C; + break; + } + + /* 6buttons specific (taken from gen-hw.txt) */ + /* A 6-button gamepad allows the extra buttons to be read based on how */ + /* many times TH is switched from 1 to 0 (and not 0 to 1). Observe the */ + /* following sequence */ + /* + TH = 1 : ?1CBRLDU 3-button pad return value + TH = 0 : ?0SA00DU 3-button pad return value + TH = 1 : ?1CBRLDU 3-button pad return value + TH = 0 : ?0SA0000 D3-0 are forced to '0' + TH = 1 : ?1CBMXYZ Extra buttons returned in D3-0 + TH = 0 : ?0SA1111 D3-0 are forced to '1' + */ + case 4: /*** Third Low ***/ + { + /* TH = 0 : ?0SA0000 D3-0 are forced to '0'*/ + data &= ~((val >> 2) & 0x30); + data &= ~0x0F; + break; + } + + case 6: /*** Fourth Low ***/ + { + /* TH = 0 : ?0SA1111 D3-0 are forced to '1'*/ + data &= ~((val >> 2) & 0x30); + break; + } + + case 7: /*** Fourth High ***/ + { + /* TH = 1 : ?1CBMXYZ Extra buttons returned in D3-0*/ + data &= ~(val & 0x30); + data &= ~((val >> 8) & 0x0F); + break; + } + } + + return data; +} + +INLINE void gamepad_write(int port, unsigned char data, unsigned char mask) +{ + /* update bits set as output only */ + data = (gamepad[port].State & ~mask) | (data & mask); + + if (input.dev[port] == DEVICE_PAD6B) + { + /* TH=0 to TH=1 transition */ + if (!(gamepad[port].State & 0x40) && (data & 0x40)) + { + gamepad[port].Counter = (gamepad[port].Counter + 2) & 6; + gamepad[port].Timeout = 0; + } + } + + /* update internal state */ + gamepad[port].State = data; +} + + +/*--------------------------------------------------------------------------*/ +/* Default ports handlers */ +/*--------------------------------------------------------------------------*/ + +unsigned char gamepad_1_read(void) +{ + return gamepad_read(0); +} + +unsigned char gamepad_2_read(void) +{ + return gamepad_read(4); +} + +void gamepad_1_write(unsigned char data, unsigned char mask) +{ + gamepad_write(0, data, mask); +} + +void gamepad_2_write(unsigned char data, unsigned char mask) +{ + gamepad_write(4, data, mask); +} + +/*--------------------------------------------------------------------------*/ +/* 4-WayPlay ports handler */ +/*--------------------------------------------------------------------------*/ + +unsigned char wayplay_1_read(void) +{ + if (pad_index < 4) + { + return gamepad_read(pad_index); + } + + /* multitap detection */ + return 0x70; +} + +unsigned char wayplay_2_read(void) +{ + return 0x7F; +} + +void wayplay_1_write(unsigned char data, unsigned char mask) +{ + if (pad_index < 4) + { + gamepad_write(pad_index, data, mask); + } +} + +void wayplay_2_write(unsigned char data, unsigned char mask) +{ + if ((mask & 0x70) == 0x70) + { + pad_index = (data & 0x70) >> 4; + } +} + + +/*--------------------------------------------------------------------------*/ +/* J-Cart memory handlers */ +/*--------------------------------------------------------------------------*/ + +unsigned int jcart_read(unsigned int address) +{ + /* TH2 output read is fixed to zero (fixes Micro Machines 2) */ + return ((gamepad_read(5) & 0x7F) | ((gamepad_read(6) & 0x3F) << 8)); +} + +void jcart_write(unsigned int address, unsigned int data) +{ + gamepad_write(5, (data & 1) << 6, 0x40); + gamepad_write(6, (data & 1) << 6, 0x40); + return; +} diff --git a/genplus-gx/core/input_hw/gamepad.h b/genplus-gx/core/input_hw/gamepad.h new file mode 100644 index 0000000000..5100e01fd4 --- /dev/null +++ b/genplus-gx/core/input_hw/gamepad.h @@ -0,0 +1,57 @@ +/*************************************************************************************** + * Genesis Plus + * 3-Buttons & 6-Buttons pad support + * Support for J-CART & 4-Way Play adapters + * + * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _GAMEPAD_H_ +#define _GAMEPAD_H_ + +/* Function prototypes */ +extern void gamepad_reset(int port); +extern void gamepad_refresh(int port); +extern unsigned char gamepad_1_read(void); +extern unsigned char gamepad_2_read(void); +extern void gamepad_1_write(unsigned char data, unsigned char mask); +extern void gamepad_2_write(unsigned char data, unsigned char mask); +extern unsigned char wayplay_1_read(void); +extern unsigned char wayplay_2_read(void); +extern void wayplay_1_write(unsigned char data, unsigned char mask); +extern void wayplay_2_write(unsigned char data, unsigned char mask); +extern unsigned int jcart_read(unsigned int address); +extern void jcart_write(unsigned int address, unsigned int data); + +#endif diff --git a/genplus-gx/core/input_hw/input.c b/genplus-gx/core/input_hw/input.c new file mode 100644 index 0000000000..ce82634dc7 --- /dev/null +++ b/genplus-gx/core/input_hw/input.c @@ -0,0 +1,374 @@ +/*************************************************************************************** + * Genesis Plus + * Input peripherals support + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "gamepad.h" +#include "lightgun.h" +#include "mouse.h" +#include "activator.h" +#include "xe_a1p.h" +#include "teamplayer.h" +#include "paddle.h" +#include "sportspad.h" +#include "terebi_oekaki.h" + +t_input input; +int old_system[2] = {-1,-1}; + + +void input_init(void) +{ + int i; + int player = 0; + + for (i=0; i> 2); + break; + } + + case DEVICE_XE_A1P: + { + xe_a1p_reset(i); + break; + } + + case DEVICE_PADDLE: + { + paddle_reset(i); + break; + } + + case DEVICE_SPORTSPAD: + { + sportspad_reset(i); + break; + } + + case DEVICE_TEREBI: + { + terebi_oekaki_reset(); + break; + } + + default: + { + break; + } + } + } + + /* Team Player */ + for (i=0; i<2; i++) + { + if (input.system[i] == SYSTEM_TEAMPLAYER) + { + teamplayer_reset(i); + } + } +} + +void input_refresh(void) +{ + int i; + for (i=0; i> 2) & 0x10); + + /* Check that TH is set as an input */ + if (io_reg[0x0F] & (0x02 << (port >> 1))) + { + /* Get current X position (phaser is only used in MS compatiblity mode) */ + int hcounter = hctab[(Z80.cycles + SMS_CYCLE_OFFSET) % MCYCLES_PER_LINE]; + + /* Compare with gun position */ + int dx = input.analog[port][0] - (hcounter << 1); + int dy = input.analog[port][1] - (v_counter); + + /* Check if current pixel is within lightgun spot ? */ + if ((abs(dy) <= 5) && (abs(dx) <= 60)) + { + /* set TH low */ + temp &= ~0x40; + + /* prevents multiple latch at each port read */ + if (lightgun.State) + { + /* latch estimated HC value */ + hvc_latch = 0x10000 | (input.x_offset + (input.analog[port][0] >> 1)); + lightgun.State = 0; + } + else + { + lightgun.State = 1; + } + } + } + + return temp & 0x7F; +} + +unsigned char phaser_1_read(void) +{ + return phaser_read(0); +} + +unsigned char phaser_2_read(void) +{ + return phaser_read(4); +} + + +/*--------------------------------------------------------------------------*/ +/* Sega Menacer */ +/*--------------------------------------------------------------------------*/ + +unsigned char menacer_read(void) +{ + /* D0=??? (INPUT_B), D1=TRIGGER (INPUT_A), D2=??? (INPUT_C), D3= START (INPUT_START) (active high) */ + /* TL & TR pins always return 0 (normally set as output) */ + /* TH always return 1 (0 on active pixel but button acquisition is always done during VBLANK) */ + unsigned data = input.pad[4] >> 4; + return ((data & 0x09) | ((data >> 1) & 0x02) | ((data << 1) & 0x04) | 0x40); +} + + +/*--------------------------------------------------------------------------*/ +/* Konami Justifiers */ +/*--------------------------------------------------------------------------*/ + +unsigned char justifier_read(void) +{ + /* Gun detection */ + if (lightgun.State & 0x40) + { + return 0x30; + } + + /* Return TRIGGER (INPUT_A) & START (INPUT_START) button status in D0-D1 (active low) */ + /* TL & TR pins should always return 1 (normally set as output) */ + /* LEFT & RIGHT pins should always return 0 */ + return (((~input.pad[lightgun.Port] >> 6) & 0x03) | 0x70); +} + +void justifier_write(unsigned char data, unsigned char mask) +{ + /* update bits set as output only, other bits are cleared (fixes Lethal Enforcers 2) */ + data &= mask; + + /* gun index */ + lightgun.Port = 4 + ((data >> 5) & 1); + + /* update internal state */ + lightgun.State = data; +} diff --git a/genplus-gx/core/input_hw/lightgun.h b/genplus-gx/core/input_hw/lightgun.h new file mode 100644 index 0000000000..0021297451 --- /dev/null +++ b/genplus-gx/core/input_hw/lightgun.h @@ -0,0 +1,51 @@ +/*************************************************************************************** + * Genesis Plus + * Sega Light Phaser, Menacer & Konami Justifiers support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _LIGHTGUN_H_ +#define _LIGHTGUN_H_ + +/* Input devices port handlers */ +extern void lightgun_reset(int index); +extern void lightgun_refresh(int port); +extern unsigned char phaser_1_read(void); +extern unsigned char phaser_2_read(void); +extern unsigned char menacer_read(void); +extern unsigned char justifier_read(void); +extern void justifier_write(unsigned char data, unsigned char mask); + +#endif diff --git a/genplus-gx/core/input_hw/mouse.c b/genplus-gx/core/input_hw/mouse.c new file mode 100644 index 0000000000..c1db5d6fdb --- /dev/null +++ b/genplus-gx/core/input_hw/mouse.c @@ -0,0 +1,159 @@ +/*************************************************************************************** + * Genesis Plus + * Sega Mouse support + * + * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +static struct +{ + uint8 State; + uint8 Counter; + uint8 Wait; + uint8 Port; +} mouse; + +void mouse_reset(int port) +{ + input.analog[port][0] = 0; + input.analog[port][1] = 0; + mouse.State = 0x60; + mouse.Counter = 0; + mouse.Wait = 0; + mouse.Port = port; +} + +unsigned char mouse_read() +{ + unsigned int temp = 0x00; + int x = input.analog[mouse.Port][0]; + int y = input.analog[mouse.Port][1]; + + switch (mouse.Counter) + { + case 0: /* initial */ + temp = 0x00; + break; + + case 1: /* xxxx1011 */ + temp = 0x0B; + break; + + case 2: /* xxxx1111 */ + temp = 0x0F; + break; + + case 3: /* xxxx1111 */ + temp = 0x0F; + break; + + case 4: /* Axis sign & overflow (not emulated) bits */ + temp |= (x < 0); + temp |= (y < 0) << 1; + /* + temp |= (abs(x) > 255) << 2; + temp |= (abs(y) > 255) << 3; + */ + break; + + case 5: /* START, A, B, C buttons state (active high) */ + temp = (input.pad[mouse.Port] >> 4) & 0x0F; + break; + + case 6: /* X Axis MSB */ + temp = (x >> 4) & 0x0F; + break; + + case 7: /* X Axis LSB */ + temp = (x & 0x0F); + break; + + case 8: /* Y Axis MSB */ + temp = (y >> 4) & 0x0F; + break; + + case 9: /* Y Axis LSB */ + temp = (y & 0x0F); + break; + } + + /* TL = busy status */ + if (mouse.Wait) + { + /* wait before ACK, fix some buggy mouse routine (Cannon Fodder, Shangai 2, Wack World,...) */ + mouse.Wait = 0; + + /* TL = !TR */ + temp |= (~mouse.State & 0x20) >> 1; + } + else + { + /* TL = TR (data is ready) */ + temp |= (mouse.State & 0x20) >> 1; + } + + return temp; +} + +void mouse_write(unsigned char data, unsigned char mask) +{ + /* update bits set as output only */ + data = (mouse.State & ~mask) | (data & mask); + + /* TH transition */ + if ((mouse.State ^ data) & 0x40) + { + /* start (TH=0) or stop (TH=1) acquisition */ + mouse.Counter = 1 - ((data & 0x40) >> 6); + } + + /* TR transition */ + if ((mouse.State ^ data) & 0x20) + { + /* acquisition in progress */ + if ((mouse.Counter > 0) && (mouse.Counter < 10)) + { + /* increment phase */ + mouse.Counter++; + } + + /* TL handshake latency */ + mouse.Wait = 1; + } + + /* update internal state */ + mouse.State = data; +} diff --git a/genplus-gx/core/input_hw/mouse.h b/genplus-gx/core/input_hw/mouse.h new file mode 100644 index 0000000000..6657d2a7f8 --- /dev/null +++ b/genplus-gx/core/input_hw/mouse.h @@ -0,0 +1,47 @@ +/*************************************************************************************** + * Genesis Plus + * Sega Mouse support + * + * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _MOUSE_H_ +#define _MOUSE_H_ + +/* Function prototypes */ +extern void mouse_reset(int port); +extern unsigned char mouse_read(void); +extern void mouse_write(unsigned char data, unsigned char mask); + +#endif diff --git a/genplus-gx/core/input_hw/paddle.c b/genplus-gx/core/input_hw/paddle.c new file mode 100644 index 0000000000..bf655c58c1 --- /dev/null +++ b/genplus-gx/core/input_hw/paddle.c @@ -0,0 +1,111 @@ +/*************************************************************************************** + * Genesis Plus + * Sega Paddle Control support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +static struct +{ + uint8 State; +} paddle[2]; + +void paddle_reset(int index) +{ + input.analog[index][0] = 128; + paddle[index>>2].State = 0x40; +} + +INLINE unsigned char paddle_read(int port) +{ + /* FIRE button status (active low) */ + unsigned char temp = ~(input.pad[port] & 0x10); + + /* Pad index */ + int index = port >> 2; + + /* Clear low bits */ + temp &= 0x70; + + /* Japanese model: automatic flip-flop */ + if (region_code < REGION_USA) + { + paddle[index].State ^= 0x40; + } + + if (paddle[index].State & 0x40) + { + /* return higher bits */ + temp |= (input.analog[port][0] >> 4) & 0x0F; + } + else + { + /* return lower bits */ + temp |= input.analog[port][0] & 0x0F; + + /* set TR low */ + temp &= ~0x20; + } + + return temp; +} + +INLINE void paddle_write(int index, unsigned char data, unsigned char mask) +{ + /* update bits set as output only */ + paddle[index].State = (paddle[index].State & ~mask) | (data & mask); +} + + +unsigned char paddle_1_read(void) +{ + return paddle_read(0); +} + +unsigned char paddle_2_read(void) +{ + return paddle_read(4); +} + +void paddle_1_write(unsigned char data, unsigned char mask) +{ + paddle_write(0, data, mask); +} + +void paddle_2_write(unsigned char data, unsigned char mask) +{ + paddle_write(1, data, mask); +} diff --git a/genplus-gx/core/input_hw/paddle.h b/genplus-gx/core/input_hw/paddle.h new file mode 100644 index 0000000000..6097a55ff6 --- /dev/null +++ b/genplus-gx/core/input_hw/paddle.h @@ -0,0 +1,49 @@ +/*************************************************************************************** + * Genesis Plus + * Sega Paddle Control support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _PADDLE_H_ +#define _PADDLE_H_ + +/* Function prototypes */ +extern void paddle_reset(int index); +extern unsigned char paddle_1_read(void); +extern unsigned char paddle_2_read(void); +extern void paddle_1_write(unsigned char data, unsigned char mask); +extern void paddle_2_write(unsigned char data, unsigned char mask); + +#endif diff --git a/genplus-gx/core/input_hw/sportspad.c b/genplus-gx/core/input_hw/sportspad.c new file mode 100644 index 0000000000..8dab4cf000 --- /dev/null +++ b/genplus-gx/core/input_hw/sportspad.c @@ -0,0 +1,134 @@ +/*************************************************************************************** + * Genesis Plus + * Sega Sports Pad support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +static struct +{ + uint8 State; + uint8 Counter; +} sportspad[2]; + +void sportspad_reset(int index) +{ + input.analog[index][0] = 128; + input.analog[index][1] = 128; + sportspad[index>>2].State = 0x40; + sportspad[index>>2].Counter = 0; +} + +INLINE unsigned char sportspad_read(int port) +{ + /* Buttons 1(B) & 2(C) status (active low) */ + unsigned char temp = ~(input.pad[port] & 0x30); + + /* Pad index */ + int index = port >> 2; + + /* Clear low bits */ + temp &= 0x70; + + /* Detect current state */ + switch (sportspad[index].Counter & 3) + { + case 1: + { + /* X position high bits */ + temp |= (input.analog[port][0] >> 4) & 0x0F; + break; + } + + case 2: + { + /* X position low bits */ + temp |= input.analog[port][0] & 0x0F; + break; + } + + case 3: + { + /* Y position high bits */ + temp |= (input.analog[port][1] >> 4) & 0x0F; + break; + } + + default: + { + /* Y position low bits */ + temp |= input.analog[port][1] & 0x0F; + break; + } + } + + return temp; +} + +INLINE void sportspad_write(int index, unsigned char data, unsigned char mask) +{ + /* update bits set as output only */ + data = (sportspad[index].State & ~mask) | (data & mask); + + /* check TH transitions */ + if ((data ^ sportspad[index].State) & 0x40) + { + sportspad[index].Counter++; + } + + /* update internal state */ + sportspad[index].State = data; +} + +unsigned char sportspad_1_read(void) +{ + return sportspad_read(0); +} + +unsigned char sportspad_2_read(void) +{ + return sportspad_read(4); +} + +void sportspad_1_write(unsigned char data, unsigned char mask) +{ + sportspad_write(0, data, mask); +} + +void sportspad_2_write(unsigned char data, unsigned char mask) +{ + sportspad_write(1, data, mask); +} diff --git a/genplus-gx/core/input_hw/sportspad.h b/genplus-gx/core/input_hw/sportspad.h new file mode 100644 index 0000000000..d5ae383cb1 --- /dev/null +++ b/genplus-gx/core/input_hw/sportspad.h @@ -0,0 +1,49 @@ +/*************************************************************************************** + * Genesis Plus + * Sega Sports Pad support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _SPORTSPAD_H_ +#define _SPORTSPAD_H_ + +/* Function prototypes */ +extern void sportspad_reset(int index); +extern unsigned char sportspad_1_read(void); +extern unsigned char sportspad_2_read(void); +extern void sportspad_1_write(unsigned char data, unsigned char mask); +extern void sportspad_2_write(unsigned char data, unsigned char mask); + +#endif diff --git a/genplus-gx/core/input_hw/teamplayer.c b/genplus-gx/core/input_hw/teamplayer.c new file mode 100644 index 0000000000..bca12a1239 --- /dev/null +++ b/genplus-gx/core/input_hw/teamplayer.c @@ -0,0 +1,176 @@ +/*************************************************************************************** + * Genesis Plus + * Team Player support + * + * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +static struct +{ + uint8 State; + uint8 Counter; + uint8 Table[12]; +} teamplayer[2]; + + +void teamplayer_init(int port) +{ + int i,padnum; + int index = 0; + + /* this table determines which gamepad input should be returned during acquisition sequence + index = teamplayer read table index: 0=1st read, 1=2nd read, ... + table = high bits are pad index, low bits are pad input shift: 0=RLDU, 4=SABC, 8=MXYZ + */ + for (i=0; i<4; i++) + { + padnum = (4 * port) + i; + if (input.dev[padnum] == DEVICE_PAD3B) + { + padnum = padnum << 4; + teamplayer[port].Table[index++] = padnum; + teamplayer[port].Table[index++] = padnum | 4; + } + else + { + padnum = padnum << 4; + teamplayer[port].Table[index++] = padnum; + teamplayer[port].Table[index++] = padnum | 4; + teamplayer[port].Table[index++] = padnum | 8; + } + } +} + +void teamplayer_reset(int port) +{ + teamplayer[port].State = 0x60; /* TH = 1, TR = 1 */ + teamplayer[port].Counter = 0; +} + +INLINE unsigned int teamplayer_read(int port) +{ + unsigned int counter = teamplayer[port].Counter; + + /* acquisition sequence */ + switch (counter) + { + case 0: /* initial state: TH = 1, TR = 1 -> RLDU = 0011 */ + { + return 0x73; + } + + case 1: /* start request: TH = 0, TR = 1 -> RLDU = 1111 */ + { + return 0x3F; + } + + case 2: + case 3: /* ack request: TH=0, TR=0/1 -> RLDU = 0000 */ + { + /* TL should match TR */ + return ((teamplayer[port].State & 0x20) >> 1); + } + + case 4: + case 5: + case 6: + case 7: /* PAD type */ + { + unsigned int retval = input.dev[(port << 2) + (counter - 4)]; + + /* TL should match TR */ + return (((teamplayer[port].State & 0x20) >> 1) | retval); + } + + default: /* PAD status */ + { + unsigned int retval = 0x0F; + + /* SEGA teamplayer returns successively PAD1 -> PAD2 -> PAD3 -> PAD4 inputs */ + unsigned int padnum = teamplayer[port].Table[counter - 8] >> 4; + + /* Each PAD inputs is obtained through 2 or 3 sequential reads: RLDU -> SACB -> MXYZ */ + retval &= ~(input.pad[padnum] >> (teamplayer[port].Table[counter - 8] & 0x0F)); + + /* TL should match TR */ + return (((teamplayer[port].State & 0x20) >> 1) | retval); + } + } +} + +INLINE void teamplayer_write(int port, unsigned char data, unsigned char mask) +{ + /* update bits set as output only */ + unsigned int state = (teamplayer[port].State & ~mask) | (data & mask); + + /* TH & TR handshaking */ + if ((teamplayer[port].State ^ state) & 0x60) + { + if (state & 0x40) + { + /* TH high -> reset counter */ + teamplayer[port].Counter = 0; + } + else + { + /* increment counter */ + teamplayer[port].Counter++; + } + + /* update internal state */ + teamplayer[port].State = state; + } +} + +unsigned char teamplayer_1_read(void) +{ + return teamplayer_read(0); +} + +unsigned char teamplayer_2_read(void) +{ + return teamplayer_read(1); +} + +void teamplayer_1_write(unsigned char data, unsigned char mask) +{ + teamplayer_write(0, data, mask); +} + +void teamplayer_2_write(unsigned char data, unsigned char mask) +{ + teamplayer_write(1, data, mask); +} diff --git a/genplus-gx/core/input_hw/teamplayer.h b/genplus-gx/core/input_hw/teamplayer.h new file mode 100644 index 0000000000..6e53c317fa --- /dev/null +++ b/genplus-gx/core/input_hw/teamplayer.h @@ -0,0 +1,50 @@ +/*************************************************************************************** + * Genesis Plus + * Team Player support + * + * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _TEAMPLAYER_H_ +#define _TEAMPLAYER_H_ + +/* Function prototypes */ +extern void teamplayer_init(int port); +extern void teamplayer_reset(int port); +extern unsigned char teamplayer_1_read(void); +extern unsigned char teamplayer_2_read(void); +extern void teamplayer_1_write(unsigned char data, unsigned char mask); +extern void teamplayer_2_write(unsigned char data, unsigned char mask); + +#endif diff --git a/genplus-gx/core/input_hw/terebi_oekaki.c b/genplus-gx/core/input_hw/terebi_oekaki.c new file mode 100644 index 0000000000..94bb89d1ac --- /dev/null +++ b/genplus-gx/core/input_hw/terebi_oekaki.c @@ -0,0 +1,77 @@ +/*************************************************************************************** + * Genesis Plus + * Terebi Oekaki graphic board support + * + * Copyright (C) 2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +static struct +{ + uint8 axis; + uint8 busy; +} tablet; + +void terebi_oekaki_reset(void) +{ + input.analog[0][0] = 128; + input.analog[0][1] = 128; + tablet.axis = 1; + tablet.busy = 1; +} + +unsigned short terebi_oekaki_read(void) +{ + uint16 data = (tablet.busy << 15) | input.analog[0][tablet.axis]; + + if (!(input.pad[0] & INPUT_B)) + { + data |= 0x100; + } + + /* clear BUSY flag */ + tablet.busy = 0; + + return data; +} + +void terebi_oekaki_write(unsigned char data) +{ + /* X (1) or Y (0) axis */ + tablet.axis = (data & 1) ^ 1; + + /* set BUSY flag */ + tablet.busy = 1; +} diff --git a/genplus-gx/core/input_hw/terebi_oekaki.h b/genplus-gx/core/input_hw/terebi_oekaki.h new file mode 100644 index 0000000000..7041c3179c --- /dev/null +++ b/genplus-gx/core/input_hw/terebi_oekaki.h @@ -0,0 +1,47 @@ +/*************************************************************************************** + * Genesis Plus + * Terebi Oekaki graphic board support + * + * Copyright (C) 2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _TEREBI_H_ +#define _TEREBI_H_ + +/* Function prototypes */ +extern void terebi_oekaki_reset(void); +extern unsigned short terebi_oekaki_read(void); +extern void terebi_oekaki_write(unsigned char data); + +#endif diff --git a/genplus-gx/core/input_hw/xe_a1p.c b/genplus-gx/core/input_hw/xe_a1p.c new file mode 100644 index 0000000000..1f02774aaa --- /dev/null +++ b/genplus-gx/core/input_hw/xe_a1p.c @@ -0,0 +1,182 @@ +/*************************************************************************************** + * Genesis Plus + * XE-A1P analog controller support + * + * Copyright (C) 2011-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +static struct +{ + uint8 State; + uint8 Counter; + uint8 Latency; +} xe_a1p[2]; + +void xe_a1p_reset(int index) +{ + input.analog[index][0] = 128; + input.analog[index][1] = 128; + input.analog[index+1][0] = 128; + index >>= 2; + xe_a1p[index].State = 0x40; + xe_a1p[index].Counter = 0; + xe_a1p[index].Latency = 0; +} + +INLINE unsigned char xe_a1p_read(int index) +{ + unsigned int temp = 0x40; + unsigned int port = index << 2; + + /* Left Stick X & Y analog values (bidirectional) */ + int x = input.analog[port][0]; + int y = input.analog[port][1]; + + /* Right Stick X or Y value (unidirectional) */ + int z = input.analog[port+1][0]; + + /* Buttons status (active low) */ + uint16 pad = ~input.pad[port]; + + /* Current internal cycle (0-7) */ + unsigned int cycle = xe_a1p[index].Counter & 7; + + /* Current 4-bit data cycle */ + /* There are eight internal data cycle for each 5 acquisition sequence */ + /* First 4 return the same 4-bit data, next 4 return next 4-bit data */ + switch (xe_a1p[index].Counter >> 2) + { + case 0: + temp |= ((pad >> 8) & 0x0F); /* E1 E2 Start Select */ + break; + case 1: + temp |= ((pad >> 4) & 0x0F); /* A B C D */ + break; + case 2: + temp |= ((x >> 4) & 0x0F); + break; + case 3: + temp |= ((y >> 4) & 0x0F); + break; + case 4: + break; + case 5: + temp |= ((z >> 4) & 0x0F); + break; + case 6: + temp |= (x & 0x0F); + break; + case 7: + temp |= (y & 0x0F); + break; + case 8: + break; + case 9: + temp |= (z & 0x0F); + break; + } + + /* TL indicates which part of data is returned (0=1st part, 1=2nd part) */ + temp |= ((cycle & 4) << 2); + + /* TR indicates if data is ready (0=ready, 1=not ready) */ + /* Fastest One input routine actually expects this bit to switch between 0 & 1 */ + /* so we make the first read of a data cycle return 1 then 0 for remaining reads */ + temp |= (!(cycle & 3) << 5); + + /* Automatically increment data cycle on each read (within current acquisition sequence) */ + cycle = (cycle + 1) & 7; + + /* Update internal cycle counter */ + xe_a1p[index].Counter = (xe_a1p[index].Counter & ~7) | cycle; + + /* Update internal latency on each read */ + xe_a1p[index].Latency++; + + return temp; +} + +INLINE void xe_a1p_write(int index, unsigned char data, unsigned char mask) +{ + /* update bits set as output only */ + data = (xe_a1p[index].State & ~mask) | (data & mask); + + /* look for TH 1->0 transitions */ + if (!(data & 0x40) && (xe_a1p[index].State & 0x40)) + { + /* reset acquisition cycle */ + xe_a1p[index].Latency = xe_a1p[index].Counter = 0; + } + else + { + /* some games immediately write new data to TH */ + /* so we make sure first sequence has actually been handled */ + if (xe_a1p[index].Latency > 2) + { + /* next acquisition sequence */ + xe_a1p[index].Counter = (xe_a1p[index].Counter & ~7) + 8; + + /* 5 sequence max with 8 cycles each */ + if (xe_a1p[index].Counter > 32) + { + xe_a1p[index].Counter = 32; + } + } + } + + /* update internal state */ + xe_a1p[index].State = data; +} + +unsigned char xe_a1p_1_read(void) +{ + return xe_a1p_read(0); +} + +unsigned char xe_a1p_2_read(void) +{ + return xe_a1p_read(1); +} + +void xe_a1p_1_write(unsigned char data, unsigned char mask) +{ + xe_a1p_write(0, data, mask); +} + +void xe_a1p_2_write(unsigned char data, unsigned char mask) +{ + xe_a1p_write(1, data, mask); +} diff --git a/genplus-gx/core/input_hw/xe_a1p.h b/genplus-gx/core/input_hw/xe_a1p.h new file mode 100644 index 0000000000..fe5b6a13bc --- /dev/null +++ b/genplus-gx/core/input_hw/xe_a1p.h @@ -0,0 +1,49 @@ +/*************************************************************************************** + * Genesis Plus + * XE-A1P analog controller support + * + * Copyright (C) 2011-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _XE_A1PH_ +#define _XE_A1PH_ + +/* Function prototypes */ +extern void xe_a1p_reset(int index); +extern unsigned char xe_a1p_1_read(void); +extern unsigned char xe_a1p_2_read(void); +extern void xe_a1p_1_write(unsigned char data, unsigned char mask); +extern void xe_a1p_2_write(unsigned char data, unsigned char mask); + +#endif diff --git a/genplus-gx/core/io_ctrl.c b/genplus-gx/core/io_ctrl.c new file mode 100644 index 0000000000..f221bf5835 --- /dev/null +++ b/genplus-gx/core/io_ctrl.c @@ -0,0 +1,591 @@ +/*************************************************************************************** + * Genesis Plus + * I/O controller (Genesis & Master System modes) + * + * Support for Master System (315-5216, 315-5237 & 315-5297), Game Gear & Mega Drive I/O chips + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "gamepad.h" +#include "lightgun.h" +#include "mouse.h" +#include "activator.h" +#include "xe_a1p.h" +#include "teamplayer.h" +#include "paddle.h" +#include "sportspad.h" + +uint8 io_reg[0x10]; + +uint8 region_code = REGION_USA; + +static struct port_t +{ + void (*data_w)(unsigned char data, unsigned char mask); + unsigned char (*data_r)(void); +} port[3]; + +static void dummy_write(unsigned char data, unsigned char mask) +{ +} + +static unsigned char dummy_read(void) +{ + return 0x7F; +} + +/***************************************************************************** + * I/O chip initialization * + * * + *****************************************************************************/ +void io_init(void) +{ + /* Initialize connected peripherals */ + input_init(); + + /* Initialize IO Ports handlers & connected peripherals */ + switch (input.system[0]) + { + case SYSTEM_MS_GAMEPAD: + { + port[0].data_w = dummy_write; + port[0].data_r = gamepad_1_read; + break; + } + + case SYSTEM_MD_GAMEPAD: + { + port[0].data_w = gamepad_1_write; + port[0].data_r = gamepad_1_read; + break; + } + + case SYSTEM_MOUSE: + { + port[0].data_w = mouse_write; + port[0].data_r = mouse_read; + break; + } + + case SYSTEM_ACTIVATOR: + { + port[0].data_w = activator_1_write; + port[0].data_r = activator_1_read; + break; + } + + case SYSTEM_XE_A1P: + { + port[0].data_w = xe_a1p_1_write; + port[0].data_r = xe_a1p_1_read; + break; + } + + case SYSTEM_WAYPLAY: + { + port[0].data_w = wayplay_1_write; + port[0].data_r = wayplay_1_read; + break; + } + + case SYSTEM_TEAMPLAYER: + { + port[0].data_w = teamplayer_1_write; + port[0].data_r = teamplayer_1_read; + break; + } + + case SYSTEM_LIGHTPHASER: + { + port[0].data_w = dummy_write; + port[0].data_r = phaser_1_read; + break; + } + + case SYSTEM_PADDLE: + { + port[0].data_w = paddle_1_write; + port[0].data_r = paddle_1_read; + break; + } + + case SYSTEM_SPORTSPAD: + { + port[0].data_w = sportspad_1_write; + port[0].data_r = sportspad_1_read; + break; + } + + default: + { + port[0].data_w = dummy_write; + port[0].data_r = dummy_read; + break; + } + } + + switch (input.system[1]) + { + case SYSTEM_MS_GAMEPAD: + { + port[1].data_w = dummy_write; + port[1].data_r = gamepad_2_read; + break; + } + + case SYSTEM_MD_GAMEPAD: + { + port[1].data_w = gamepad_2_write; + port[1].data_r = gamepad_2_read; + break; + } + + case SYSTEM_MOUSE: + { + port[1].data_w = mouse_write; + port[1].data_r = mouse_read; + break; + } + + case SYSTEM_XE_A1P: + { + port[1].data_w = xe_a1p_2_write; + port[1].data_r = xe_a1p_2_read; + break; + } + + case SYSTEM_ACTIVATOR: + { + port[1].data_w = activator_2_write; + port[1].data_r = activator_2_read; + break; + } + + case SYSTEM_MENACER: + { + port[1].data_w = dummy_write; + port[1].data_r = menacer_read; + break; + } + + case SYSTEM_JUSTIFIER: + { + port[1].data_w = justifier_write; + port[1].data_r = justifier_read; + break; + } + + case SYSTEM_WAYPLAY: + { + port[1].data_w = wayplay_2_write; + port[1].data_r = wayplay_2_read; + break; + } + + case SYSTEM_TEAMPLAYER: + { + port[1].data_w = teamplayer_2_write; + port[1].data_r = teamplayer_2_read; + break; + } + + case SYSTEM_LIGHTPHASER: + { + port[1].data_w = dummy_write; + port[1].data_r = phaser_2_read; + break; + } + + case SYSTEM_PADDLE: + { + port[1].data_w = paddle_2_write; + port[1].data_r = paddle_2_read; + break; + } + + case SYSTEM_SPORTSPAD: + { + port[1].data_w = sportspad_2_write; + port[1].data_r = sportspad_2_read; + break; + } + + default: + { + port[1].data_w = dummy_write; + port[1].data_r = dummy_read; + break; + } + } + + /* External Port (unconnected) */ + port[2].data_w = dummy_write; + port[2].data_r = dummy_read; +} + + +void io_reset(void) +{ + /* Reset I/O registers */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + io_reg[0x00] = region_code | (config.bios & 1); + io_reg[0x01] = 0x00; + io_reg[0x02] = 0x00; + io_reg[0x03] = 0x00; + io_reg[0x04] = 0x00; + io_reg[0x05] = 0x00; + io_reg[0x06] = 0x00; + io_reg[0x07] = 0xFF; + io_reg[0x08] = 0x00; + io_reg[0x09] = 0x00; + io_reg[0x0A] = 0xFF; + io_reg[0x0B] = 0x00; + io_reg[0x0C] = 0x00; + io_reg[0x0D] = 0xFB; + io_reg[0x0E] = 0x00; + io_reg[0x0F] = 0x00; + + /* CD unit detection */ + if (system_hw != SYSTEM_MCD) + { + io_reg[0x00] |= 0x20; + } + } + else + { + /* Game Gear specific registers */ + io_reg[0x00] = 0x80 | (region_code >> 1); + io_reg[0x01] = 0x00; + io_reg[0x02] = 0xFF; + io_reg[0x03] = 0x00; + io_reg[0x04] = 0xFF; + io_reg[0x05] = 0x00; + io_reg[0x06] = 0xFF; + + /* initial !RESET input */ + io_reg[0x0D] = IO_RESET_HI; + + /* default !CONT input */ + if (system_hw != SYSTEM_PBC) + { + io_reg[0x0D] |= IO_CONT1_HI; + } + + /* Control registers */ + io_reg[0x0E] = 0x00; + io_reg[0x0F] = 0xFF; + } + + /* Reset connected peripherals */ + input_reset(); +} + + +/***************************************************************************** + * I/O ports access from 68k (Genesis mode) * + * * + *****************************************************************************/ + +void io_68k_write(unsigned int offset, unsigned int data) +{ + switch (offset) + { + case 0x01: /* Port A Data */ + case 0x02: /* Port B Data */ + case 0x03: /* Port C Data */ + { + io_reg[offset] = data; + port[offset-1].data_w(data, io_reg[offset + 3]); + return; + } + + case 0x04: /* Port A Ctrl */ + case 0x05: /* Port B Ctrl */ + case 0x06: /* Port C Ctrl */ + { + if (data != io_reg[offset]) + { + io_reg[offset] = data; + port[offset-4].data_w(io_reg[offset-3], data); + } + return; + } + + case 0x07: /* Port A TxData */ + case 0x0A: /* Port B TxData */ + case 0x0D: /* Port C TxData */ + { + io_reg[offset] = data; + return; + } + + case 0x09: /* Port A S-Ctrl */ + case 0x0C: /* Port B S-Ctrl */ + case 0x0F: /* Port C S-Ctrl */ + { + io_reg[offset] = data & 0xF8; + return; + } + + default: /* Read-only ports */ + { + return; + } + } +} + +unsigned int io_68k_read(unsigned int offset) +{ + switch(offset) + { + case 0x01: /* Port A Data */ + case 0x02: /* Port B Data */ + case 0x03: /* Port C Data */ + { + unsigned int mask = 0x80 | io_reg[offset + 3]; + unsigned int data = port[offset-1].data_r(); + return (io_reg[offset] & mask) | (data & ~mask); + } + + default: /* return register value */ + { + return io_reg[offset]; + } + } +} + + +/***************************************************************************** + * I/O ports access from Z80 * + * * + *****************************************************************************/ + +void io_z80_write(unsigned int offset, unsigned int data, unsigned int cycles) +{ + if (offset) + { + /* I/O Control register */ + if (region_code & REGION_USA) + { + /* + Bit Function + -------------- + D7 : Port B TH pin output level (1=high, 0=low) + D6 : Port B TR pin output level (1=high, 0=low) + D5 : Port A TH pin output level (1=high, 0=low) + D4 : Port A TR pin output level (1=high, 0=low) + D3 : Port B TH pin direction (1=input, 0=output) + D2 : Port B TR pin direction (1=input, 0=output) + D1 : Port A TH pin direction (1=input, 0=output) + D0 : Port A TR pin direction (1=input, 0=output) + */ + + /* Send TR/TH state to connected peripherals */ + port[0].data_w((data << 1) & 0x60, (~io_reg[0x0F] << 5) & 0x60); + port[1].data_w((data >> 1) & 0x60, (~io_reg[0x0F] << 3) & 0x60); + + + /* Check for TH low-to-high transitions on both ports */ + if ((!(io_reg[0x0F] & 0x80) && (data & 0x80)) || + (!(io_reg[0x0F] & 0x20) && (data & 0x20))) + { + /* Latch new HVC */ + hvc_latch = hctab[cycles % MCYCLES_PER_LINE] | 0x10000; + } + + /* Update I/O Control register */ + io_reg[0x0F] = data; + } + else + { + /* TH output is fixed to 0 & TR is always an input on japanese hardware */ + io_reg[0x0F] = (data | 0x05) & 0x5F; + + /* Port $DD bits D4-D5 return D0-D2 (cf. http://www2.odn.ne.jp/~haf09260/Sms/EnrSms.htm) */ + io_reg[0x0D] = ((data & 0x01) << 4) | ((data & 0x04) << 3); + } + } + else + { + /* Update Memory Control register */ + io_reg[0x0E] = data; + + /* Switch cartridge & BIOS ROM */ + sms_cart_switch(~data); + } +} + +unsigned int io_z80_read(unsigned int offset) +{ + /* Read port A & port B input data */ + unsigned int data = (port[0].data_r()) | (port[1].data_r() << 8); + + /* I/O control register value */ + unsigned int ctrl = io_reg[0x0F]; + + /* I/O ports */ + if (offset) + { + /* + Bit Function + -------------- + D7 : Port B TH pin input + D6 : Port A TH pin input + D5 : CONT input (0 on Mega Drive hardware, 1 otherwise) + D4 : RESET button (1: default, 0: pressed, only on Master System hardware) + D3 : Port B TR pin input + D2 : Port B TL pin input + D1 : Port B Right pin input + D0 : Port B Left pin input + */ + data = ((data >> 10) & 0x0F) | (data & 0x40) | ((data >> 7) & 0x80) | io_reg[0x0D]; + + /* clear !RESET input */ + io_reg[0x0D] |= IO_RESET_HI; + + /* Adjust port B TH state if configured as output */ + if (!(ctrl & 0x08)) + { + data &= ~0x80; + data |= (ctrl & 0x80); + } + + /* Adjust port A TH state if configured as output */ + if (!(ctrl & 0x02)) + { + data &= ~0x40; + data |= ((ctrl & 0x20) << 1); + } + + /* Adjust port B TR state if configured as output */ + if (!(ctrl & 0x04)) + { + data &= ~0x08; + data |= ((ctrl & 0x40) >> 3); + } + } + else + { + /* + Bit Function + -------------- + D7 : Port B Down pin input + D6 : Port B Up pin input + D5 : Port A TR pin input + D4 : Port A TL pin input + D3 : Port A Right pin input + D2 : Port A Left pin input + D1 : Port A Down pin input + D0 : Port A Up pin input + */ + data = (data & 0x3F) | ((data >> 2) & 0xC0); + + /* Adjust port A TR state if configured as output */ + if (!(ctrl & 0x01)) + { + data &= ~0x20; + data |= ((ctrl & 0x10) << 1); + } + } + + return data; +} + + +/***************************************************************************** + * Game Gear communication ports access * + * * + *****************************************************************************/ + +void io_gg_write(unsigned int offset, unsigned int data) +{ + switch (offset) + { + case 1: /* Parallel data register */ + io_reg[1] = data; + return; + + case 2: /* Data direction register and NMI enable */ + io_reg[2] = data; + return; + + case 3: /* Transmit data buffer */ + io_reg[3] = data; + return; + + case 5: /* Serial control (bits 0-2 are read-only) */ + io_reg[5] = data & 0xF8; + return; + + case 6: /* PSG Stereo output control */ + io_reg[6] = data; + SN76489_Config(Z80.cycles, config.psg_preamp, config.psgBoostNoise, data); + return; + + default: /* Read-only */ + return; + } +} + +unsigned int io_gg_read(unsigned int offset) +{ + switch (offset) + { + case 0: /* Mode Register */ + return (io_reg[0] & ~(input.pad[0] & INPUT_START)); + + case 1: /* Parallel data register (not connected) */ + return ((io_reg[1] & ~(io_reg[2] & 0x7F)) | (io_reg[2] & 0x7F)); + + case 2: /* Data direction register and NMI enable */ + return io_reg[2]; + + case 3: /* Transmit data buffer */ + return io_reg[3]; + + case 4: /* Receive data buffer */ + return io_reg[4]; + + case 5: /* Serial control */ + return io_reg[5]; + + default: /* Write-Only */ + return 0xFF; + } +} + diff --git a/genplus-gx/core/io_ctrl.h b/genplus-gx/core/io_ctrl.h new file mode 100644 index 0000000000..addc259725 --- /dev/null +++ b/genplus-gx/core/io_ctrl.h @@ -0,0 +1,68 @@ +/*************************************************************************************** + * Genesis Plus + * I/O controller + * + * Support for Master System (315-5216, 315-5237 & 315-5297), Game Gear & Mega Drive I/O chips + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _IO_CTRL_H_ +#define _IO_CTRL_H_ + +#define IO_RESET_HI 0x10 +#define IO_CONT1_HI 0x20 + +#define REGION_JAPAN_NTSC 0x00 +#define REGION_JAPAN_PAL 0x40 +#define REGION_USA 0x80 +#define REGION_EUROPE 0xC0 + +/* Global variables */ +extern uint8 io_reg[0x10]; +extern uint8 region_code; + +/* Function prototypes */ +extern void io_init(void); +extern void io_reset(void); +extern void io_68k_write(unsigned int offset, unsigned int data); +extern unsigned int io_68k_read(unsigned int offset); +extern void io_z80_write(unsigned int offset, unsigned int data, unsigned int cycles); +extern unsigned int io_z80_read(unsigned int offset); +extern void io_gg_write(unsigned int offset, unsigned int data); +extern unsigned int io_gg_read(unsigned int offset); + +#endif /* _IO_CTRL_H_ */ + diff --git a/genplus-gx/core/loadrom.c b/genplus-gx/core/loadrom.c new file mode 100644 index 0000000000..1cda87501e --- /dev/null +++ b/genplus-gx/core/loadrom.c @@ -0,0 +1,1136 @@ +/*************************************************************************************** + * Genesis Plus + * ROM Loading Support + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include +#include "shared.h" + +/*** ROM Information ***/ +#define ROMCONSOLE 256 +#define ROMCOPYRIGHT 272 +#define ROMDOMESTIC 288 +#define ROMWORLD 336 +#define ROMTYPE 384 +#define ROMPRODUCT 386 +#define ROMCHECKSUM 398 +#define ROMIOSUPPORT 400 +#define ROMROMSTART 416 +#define ROMROMEND 420 +#define ROMRAMINFO 424 +#define ROMRAMSTART 436 +#define ROMRAMEND 440 +#define ROMMODEMINFO 444 +#define ROMMEMO 456 +#define ROMCOUNTRY 496 + +#define P3BUTTONS 1 +#define P6BUTTONS 2 +#define PKEYBOARD 4 +#define PPRINTER 8 +#define PBALL 16 +#define PFLOPPY 32 +#define PACTIVATOR 64 +#define PTEAMPLAYER 128 +#define PMSYSTEMPAD 256 +#define PSERIAL 512 +#define PTABLET 1024 +#define PPADDLE 2048 +#define PCDROM 4096 +#define PMOUSE 8192 + +#define MAXCOMPANY 64 +#define MAXPERIPHERALS 15 + +typedef struct +{ + char companyid[6]; + char company[26]; +} COMPANYINFO; + +typedef struct +{ + char pID[2]; + char pName[14]; +} PERIPHERALINFO; + + +ROMINFO rominfo; +uint8 romtype; + +static uint8 rom_region; + +/*************************************************************************** + * Genesis ROM Manufacturers + * + * Based on the document provided at + * http://www.zophar.net/tech/files/Genesis_ROM_Format.txt + **************************************************************************/ +static const COMPANYINFO companyinfo[MAXCOMPANY] = +{ + {"ACLD", "Ballistic"}, + {"RSI", "Razorsoft"}, + {"SEGA", "SEGA"}, + {"TREC", "Treco"}, + {"VRGN", "Virgin Games"}, + {"WSTN", "Westone"}, + {"10", "Takara"}, + {"11", "Taito or Accolade"}, + {"12", "Capcom"}, + {"13", "Data East"}, + {"14", "Namco or Tengen"}, + {"15", "Sunsoft"}, + {"16", "Bandai"}, + {"17", "Dempa"}, + {"18", "Technosoft"}, + {"19", "Technosoft"}, + {"20", "Asmik"}, + {"22", "Micronet"}, + {"23", "Vic Tokai"}, + {"24", "American Sammy"}, + {"29", "Kyugo"}, + {"32", "Wolfteam"}, + {"33", "Kaneko"}, + {"35", "Toaplan"}, + {"36", "Tecmo"}, + {"40", "Toaplan"}, + {"42", "UFL Company Limited"}, + {"43", "Human"}, + {"45", "Game Arts"}, + {"47", "Sage's Creation"}, + {"48", "Tengen"}, + {"49", "Renovation or Telenet"}, + {"50", "Electronic Arts"}, + {"56", "Razorsoft"}, + {"58", "Mentrix"}, + {"60", "Victor Musical Ind."}, + {"69", "Arena"}, + {"70", "Virgin"}, + {"73", "Soft Vision"}, + {"74", "Palsoft"}, + {"76", "Koei"}, + {"79", "U.S. Gold"}, + {"81", "Acclaim/Flying Edge"}, + {"83", "Gametek"}, + {"86", "Absolute"}, + {"87", "Mindscape"}, + {"93", "Sony"}, + {"95", "Konami"}, + {"97", "Tradewest"}, + {"100", "T*HQ Software"}, + {"101", "Tecmagik"}, + {"112", "Designer Software"}, + {"113", "Psygnosis"}, + {"119", "Accolade"}, + {"120", "Code Masters"}, + {"125", "Interplay"}, + {"130", "Activision"}, + {"132", "Shiny & Playmates"}, + {"144", "Atlus"}, + {"151", "Infogrames"}, + {"161", "Fox Interactive"}, + {"177", "Ubisoft"}, + {"239", "Disney Interactive"}, + {"---", "Unknown"} +}; + +/*************************************************************************** + * Genesis Peripheral Information + * + * Based on the document provided at + * http://www.zophar.net/tech/files/Genesis_ROM_Format.txt + ***************************************************************************/ +static const PERIPHERALINFO peripheralinfo[MAXPERIPHERALS] = +{ + {"J", "3B Joypad"}, + {"6", "6B Joypad"}, + {"K", "Keyboard"}, + {"P", "Printer"}, + {"B", "Control Ball"}, + {"F", "Floppy Drive"}, + {"L", "Activator"}, + {"4", "Team Player"}, + {"0", "MS Joypad"}, + {"R", "RS232C Serial"}, + {"T", "Tablet"}, + {"V", "Paddle"}, + {"C", "CD-ROM"}, + {"M", "Mega Mouse"}, + {"G", "Menacer"}, +}; + +/*************************************************************************** + * + * Compute ROM real checksum. + ***************************************************************************/ +static uint16 getchecksum(uint8 *rom, int length) +{ + int i; + uint16 checksum = 0; + + for (i = 0; i < length; i += 2) + { + checksum += ((rom[i] << 8) + rom[i + 1]); + } + + return checksum; +} + + +/*************************************************************************** + * deinterleave_block + * + * Convert interleaved (.smd) ROM files. + ***************************************************************************/ +static void deinterleave_block(uint8 * src) +{ + int i; + uint8 block[0x4000]; + memcpy (block, src, 0x4000); + for (i = 0; i < 0x2000; i += 1) + { + src[i * 2 + 0] = block[0x2000 + (i)]; + src[i * 2 + 1] = block[0x0000 + (i)]; + } +} + +/*************************************************************************** + * + * Pass a pointer to the ROM base address. + ***************************************************************************/ +void getrominfo(char *romheader) +{ + /* Clear ROM info structure */ + memset (&rominfo, 0, sizeof (ROMINFO)); + + /* Genesis ROM header support */ + if (system_hw & SYSTEM_MD) + { + int i,j; + + memcpy (&rominfo.consoletype, romheader + ROMCONSOLE, 16); + memcpy (&rominfo.copyright, romheader + ROMCOPYRIGHT, 16); + + /* Domestic (japanese) name */ + rominfo.domestic[0] = romheader[ROMDOMESTIC]; + j = 1; + for (i=1; i<48; i++) + { + if ((rominfo.domestic[j-1] != 32) || (romheader[ROMDOMESTIC + i] != 32)) + { + rominfo.domestic[j] = romheader[ROMDOMESTIC + i]; + j++; + } + } + rominfo.domestic[j] = 0; + + /* International name */ + rominfo.international[0] = romheader[ROMWORLD]; + j=1; + for (i=1; i<48; i++) + { + if ((rominfo.international[j-1] != 32) || (romheader[ROMWORLD + i] != 32)) + { + rominfo.international[j] = romheader[ROMWORLD + i]; + j++; + } + } + rominfo.international[j] = 0; + + /* ROM informations */ + memcpy (&rominfo.ROMType, romheader + ROMTYPE, 2); + memcpy (&rominfo.product, romheader + ROMPRODUCT, 12); + memcpy (&rominfo.checksum, romheader + ROMCHECKSUM, 2); + memcpy (&rominfo.romstart, romheader + ROMROMSTART, 4); + memcpy (&rominfo.romend, romheader + ROMROMEND, 4); + memcpy (&rominfo.country, romheader + ROMCOUNTRY, 16); + + /* Checksums */ +#ifdef LSB_FIRST + rominfo.checksum = (rominfo.checksum >> 8) | ((rominfo.checksum & 0xff) << 8); +#endif + rominfo.realchecksum = getchecksum(((uint8 *) cart.rom) + 0x200, cart.romsize - 0x200); + + /* Supported peripherals */ + rominfo.peripherals = 0; + for (i = 0; i < 14; i++) + for (j=0; j < 14; j++) + if (romheader[ROMIOSUPPORT+i] == peripheralinfo[j].pID[0]) + rominfo.peripherals |= (1 << j); + } + else + { + uint16 offset = 0; + + /* detect Master System ROM header */ + if (!memcmp (&romheader[0x1ff0], "TMR SEGA", 8)) + { + offset = 0x1ff0; + } + else if (!memcmp (&romheader[0x3ff0], "TMR SEGA", 8)) + { + offset = 0x3ff0; + } + else if (!memcmp (&romheader[0x7ff0], "TMR SEGA", 8)) + { + offset = 0x7ff0; + } + + /* if found, get infos from header */ + if (offset) + { + /* checksum */ + rominfo.checksum = romheader[offset + 0x0a] | (romheader[offset + 0x0b] << 8); + + /* product code & version */ + sprintf(&rominfo.product[0], "%02d", romheader[offset + 0x0e] >> 4); + sprintf(&rominfo.product[2], "%02x", romheader[offset + 0x0d]); + sprintf(&rominfo.product[4], "%02x", romheader[offset + 0x0c]); + sprintf(&rominfo.product[6], "-%d", romheader[offset + 0x0e] & 0x0F); + + /* region code */ + switch (romheader[offset + 0x0f] >> 4) + { + case 3: + strcpy(rominfo.country,"SMS Japan"); + break; + case 4: + strcpy(rominfo.country,"SMS Export"); + break; + case 5: + strcpy(rominfo.country,"GG Japan"); + break; + case 6: + strcpy(rominfo.country,"GG Export"); + break; + case 7: + strcpy(rominfo.country,"GG International"); + break; + default: + sprintf(rominfo.country,"Unknown (%d)", romheader[offset + 0x0f] >> 4); + break; + } + + /* ROM size */ + rominfo.romstart = 0; + switch (romheader[offset + 0x0f] & 0x0F) + { + case 0x00: + rominfo.romend = 0x3FFFF; + break; + case 0x01: + rominfo.romend = 0x7FFFF; + break; + case 0x02: + rominfo.romend = 0xFFFFF; + break; + case 0x0a: + rominfo.romend = 0x1FFF; + break; + case 0x0b: + rominfo.romend = 0x3FFF; + break; + case 0x0c: + rominfo.romend = 0x7FFF; + break; + case 0x0d: + rominfo.romend = 0xBFFF; + break; + case 0x0e: + rominfo.romend = 0xFFFF; + break; + case 0x0f: + rominfo.romend = 0x1FFFF; + break; + } + } + } +} + +/*************************************************************************** + * load_bios + * + * Load current system BIOS file. + * + * Return loaded size (-1 if already loaded) + * + ***************************************************************************/ +int load_bios(void) +{ + int size = 0; + + switch (system_hw) + { + case SYSTEM_MCD: + { + /* check if CD BOOTROM is already loaded */ + if (!(system_bios & 0x10) || ((system_bios & 0x0c) != (region_code >> 4))) + { + /* load CD BOOTROM (fixed 128KB size) */ + switch (region_code) + { + case REGION_USA: + size = load_archive(CD_BIOS_US, scd.bootrom, sizeof(scd.bootrom), 0); + break; + case REGION_EUROPE: + size = load_archive(CD_BIOS_EU, scd.bootrom, sizeof(scd.bootrom), 0); + break; + default: + size = load_archive(CD_BIOS_JP, scd.bootrom, sizeof(scd.bootrom), 0); + break; + } + + /* CD BOOTROM loaded ? */ + if (size > 0) + { +#ifdef LSB_FIRST + /* Byteswap ROM to optimize 16-bit access */ + int i; + for (i = 0; i < size; i += 2) + { + uint8 temp = scd.bootrom[i]; + scd.bootrom[i] = scd.bootrom[i+1]; + scd.bootrom[i+1] = temp; + } +#endif + /* mark CD BIOS as being loaded */ + system_bios = system_bios | 0x10; + + /* loaded BIOS region */ + system_bios = (system_bios & 0xf0) | (region_code >> 4); + } + + return size; + } + + return -1; + } + + case SYSTEM_GG: + case SYSTEM_GGMS: + { + /* check if Game Gear BOOTROM is already loaded */ + if (!(system_bios & SYSTEM_GG)) + { + /* mark both Master System & Game Gear BOOTROM as unloaded */ + system_bios &= ~(SYSTEM_SMS | SYSTEM_GG); + + /* BOOTROM is stored above cartridge ROM area (max. 4MB) */ + if (cart.romsize <= 0x400000) + { + /* load Game Gear BOOTROM file */ + size = load_archive(GG_BIOS, cart.rom + 0x400000, 0x100000, 0); + + if (size > 0) + { + /* mark Game Gear BOOTROM as loaded */ + system_bios |= SYSTEM_GG; + } + } + + return size; + } + + return -1; + } + + case SYSTEM_SMS: + case SYSTEM_SMS2: + { + /* check if Master System BOOTROM is already loaded */ + if (!(system_bios & SYSTEM_SMS) || ((system_bios & 0x0c) != (region_code >> 4))) + { + /* mark both Master System & Game Gear BOOTROM as unloaded */ + system_bios &= ~(SYSTEM_SMS | SYSTEM_GG); + + /* BOOTROM is stored above cartridge ROM area (max. 4MB) */ + if (cart.romsize <= 0x400000) + { + /* load Master System BOOTROM file */ + switch (region_code) + { + case REGION_USA: + size = load_archive(MS_BIOS_US, cart.rom + 0x400000, 0x400000, 0); + break; + case REGION_EUROPE: + size = load_archive(MS_BIOS_EU, cart.rom + 0x400000, 0x400000, 0); + break; + default: + size = load_archive(MS_BIOS_JP, cart.rom + 0x400000, 0x400000, 0); + break; + } + + if (size > 0) + { + /* mark Master System BOOTROM as loaded */ + system_bios |= SYSTEM_SMS; + + /* loaded BOOTROM region */ + system_bios = (system_bios & 0xf0) | (region_code >> 4); + } + } + + return size; + } + + return -1; + } + + default: + { + return 0; + } + } +} + +/*************************************************************************** + * load_rom + * + * Load a new ROM file. + * + * Return 0 on error, 1 on success + * + ***************************************************************************/ +int load_rom(char *filename) +{ + int i, size; + + /* clear any existing patches */ + ggenie_shutdown(); + areplay_shutdown(); + + /* check previous loaded ROM size */ + if (cart.romsize > 0x800000) + { + /* assume no CD is currently loaded */ + cdd.loaded = 0; + } + + /* auto-detect CD image files */ + size = 0; //cdd_load(filename, (char *)(cart.rom)); + if (size < 0) + { + /* error opening file */ + return 0; + } + + if (size > 0) + { + /* CD image file loaded */ + system_hw = SYSTEM_MCD; + } + else + { + /* load file into ROM buffer */ + char extension[4]; + size = load_archive(filename, cart.rom, sizeof(cart.rom), extension); + if (!size) + { + /* mark all BOOTROM as unloaded since they could have been overwritten */ + system_bios &= ~(0x10 | SYSTEM_SMS | SYSTEM_GG); + return 0; + } + + /* mark BOOTROM as unloaded if they have been overwritten by cartridge ROM */ + if (size > 0x800000) + { + /* CD BIOS ROM are loaded at the start of CD area */ + system_bios &= ~0x10; + } + else if (size > 0x400000) + { + /* Master System or Game Gear BIOS ROM are loaded within $400000-$4FFFFF area */ + system_bios &= ~(SYSTEM_SMS | SYSTEM_GG); + } + + /* convert lower case to upper case */ + *(uint32 *)(extension) &= 0xdfdfdfdf; + + /* auto-detect system hardware from ROM file extension */ + if (!memcmp("SMS", &extension[0], 3)) + { + /* Master System II hardware */ + system_hw = SYSTEM_SMS2; + } + else if (!memcmp("GG", &extension[1], 2)) + { + /* Game Gear hardware (GG mode) */ + system_hw = SYSTEM_GG; + } + else if (!memcmp("SG", &extension[1], 2)) + { + /* SG-1000 hardware */ + system_hw = SYSTEM_SG; + } + else + { + /* Mega Drive hardware (Genesis mode) */ + system_hw = SYSTEM_MD; + + /* decode .MDX format */ + if (!memcmp("MDX", &extension[0], 3)) + { + for (i = 4; i < size - 1; i++) + { + cart.rom[i-4] = cart.rom[i] ^ 0x40; + } + size = size - 5; + } + + /* auto-detect byte-swapped dumps */ + if (!memcmp((char *)(cart.rom + 0x100),"ESAGM GE ARDVI E", 16) || + !memcmp((char *)(cart.rom + 0x100),"ESAGG NESESI", 12)) + { + for(i = 0; i < size; i += 2) + { + uint8 temp = cart.rom[i]; + cart.rom[i] = cart.rom[i+1]; + cart.rom[i+1] = temp; + } + } + } + + /* auto-detect 512 byte extra header */ + if (memcmp((char *)(cart.rom + 0x100), "SEGA", 4) && ((size / 512) & 1) && !(size % 512)) + { + /* remove header */ + size -= 512; + memcpy (cart.rom, cart.rom + 512, size); + + /* assume interleaved Genesis ROM format (.smd) */ + if (system_hw == SYSTEM_MD) + { + for (i = 0; i < (size / 0x4000); i++) + { + deinterleave_block (cart.rom + (i * 0x4000)); + } + } + } + } + + /* initialize ROM size */ + cart.romsize = size; + + /* get infos from ROM header */ + getrominfo((char *)(cart.rom)); + + /* set console region */ + get_region((char *)(cart.rom)); + + /* CD image file */ + if (system_hw == SYSTEM_MCD) + { + /* load CD BOOT ROM */ + if (!load_bios()) + { + /* unmount CD image */ + cdd_unload(); + + /* error loading CD BOOT ROM */ + return (0); + } + + /* boot from CD */ + scd.cartridge.boot = 0x00; + } + +#ifdef LSB_FIRST + /* 16-bit ROM specific */ + else if (system_hw == SYSTEM_MD) + { + /* Byteswap ROM to optimize 16-bit access */ + for (i = 0; i < cart.romsize; i += 2) + { + uint8 temp = cart.rom[i]; + cart.rom[i] = cart.rom[i+1]; + cart.rom[i+1] = temp; + } + } +#endif + + /* Save auto-detected system hardware */ + romtype = system_hw; + + /* PICO ROM */ + if (strstr(rominfo.consoletype, "SEGA PICO") != NULL) + { + /* PICO hardware */ + system_hw = SYSTEM_PICO; + } + + /* CD BOOTROM */ + else if (strstr(rominfo.ROMType, "BR") != NULL) + { + /* enable CD hardware */ + system_hw = SYSTEM_MCD; + + /* boot from CD */ + scd.cartridge.boot = 0x00; + + /* copy ROM to BOOTROM area */ + memcpy(scd.bootrom, cart.rom, sizeof(scd.bootrom)); + + /* mark CD BIOS as being loaded */ + system_bios = system_bios | 0x10; + + /* loaded CD BIOS region */ + system_bios = (system_bios & 0xf0) | (region_code >> 4); + } + + /* ROM cartridges with CD support */ + else if ((strstr(rominfo.domestic,"FLUX") != NULL) || + (strstr(rominfo.domestic,"WONDER LIBRARY") != NULL) || + (strstr(rominfo.product,"T-5740") != NULL)) + { + /* check if console hardware is set to AUTO */ + if (config.system == 0x00) + { + /* auto-enable CD hardware */ + system_hw = SYSTEM_MCD; + + /* try to load CD BOOTROM */ + if (load_bios()) + { + /* boot from cartridge */ + scd.cartridge.boot = 0x40; + + /* automatically load associated .iso image */ + strncpy(&filename[strlen(filename) - 4], ".iso", 4); + cdd_load(filename, (char *)cdc.ram); + } + else + { + /* if not found, disable CD hardware */ + system_hw = SYSTEM_MD; + } + } + } + + /* Force system hardware if requested */ + if (config.system == SYSTEM_MD) + { + if (!(system_hw & SYSTEM_MD)) + { + /* Mega Drive in MS compatibility mode */ + system_hw = SYSTEM_PBC; + } + } + else if (config.system == SYSTEM_GG) + { + if (system_hw != SYSTEM_GG) + { + /* Game Gear in MS compatibility mode */ + system_hw = SYSTEM_GGMS; + } + } + else if (config.system) + { + system_hw = config.system; + } + + /* restore previous input settings */ + if (old_system[0] != -1) + { + input.system[0] = old_system[0]; + } + if (old_system[1] != -1) + { + input.system[1] = old_system[1]; + } + + /* default gun settings */ + input.x_offset = (input.system[1] == SYSTEM_MENACER) ? 64 : 0; + input.y_offset = 0; + + /* autodetect gun support */ + if (strstr(rominfo.international,"MENACER") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 82; + input.y_offset = 0; + } + else if (strstr(rominfo.international,"T2 ; THE ARCADE GAME") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 133; + input.y_offset = -8; + } + else if (strstr(rominfo.international,"BODY COUNT") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 68; + input.y_offset = -24; + } + else if (strstr(rominfo.international,"CORPSE KILLER") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 64; + input.y_offset = -8; + } + else if (strstr(rominfo.international,"CRIME PATROL") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 61; + input.y_offset = 0; + } + else if (strstr(rominfo.international,"MAD DOG II THE LOST GOLD") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 70; + input.y_offset = 18; + } + else if (strstr(rominfo.international,"MAD DOG MCCREE") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 49; + input.y_offset = 0; + } + else if (strstr(rominfo.international,"WHO SHOT JOHNNY ROCK?") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 60; + input.y_offset = 30; + } + else if ((strstr(rominfo.international,"LETHAL ENFORCERS") != NULL) || + (strstr(rominfo.international,"SNATCHER") != NULL)) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force JUSTIFIER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_JUSTIFIER; + input.x_offset = (strstr(rominfo.international,"GUN FIGHTERS") != NULL) ? 24 : 0; + input.y_offset = 0; + } + + return(1); +} + +/**************************************************************************** + * get_region + * + * Set console region from ROM header passed as parameter or + * from previous auto-detection (if NULL) + * + ****************************************************************************/ +void get_region(char *romheader) +{ + /* region auto-detection ? */ + if (romheader) + { + /* Mega CD image */ + if (system_hw == SYSTEM_MCD) + { + /* security code */ + switch (romheader[0x20b]) + { + case 0x7a: + region_code = REGION_USA; + break; + + case 0x64: + region_code = REGION_EUROPE; + break; + + default: + region_code = REGION_JAPAN_NTSC; + break; + } + } + + /* 16-bit cartridge */ + else if (system_hw & SYSTEM_MD) + { + /* country codes used to differentiate region */ + /* 0001 = japan ntsc (1) */ + /* 0010 = japan pal (2) -> does not exist ? */ + /* 0100 = usa (4) */ + /* 1000 = europe (8) */ + int country = 0; + + /* from Gens */ + if (!memcmp(rominfo.country, "eur", 3)) country |= 8; + else if (!memcmp(rominfo.country, "EUR", 3)) country |= 8; + else if (!memcmp(rominfo.country, "jap", 3)) country |= 1; + else if (!memcmp(rominfo.country, "JAP", 3)) country |= 1; + else if (!memcmp(rominfo.country, "usa", 3)) country |= 4; + else if (!memcmp(rominfo.country, "USA", 3)) country |= 4; + else + { + int i; + char c; + + /* look for each characters */ + for(i = 0; i < 4; i++) + { + c = toupper((int)rominfo.country[i]); + + if (c == 'U') country |= 4; + else if (c == 'J') country |= 1; + else if (c == 'E') country |= 8; + else if (c == 'K') country |= 1; + else if (c < 16) country |= c; + else if ((c >= '0') && (c <= '9')) country |= c - '0'; + else if ((c >= 'A') && (c <= 'F')) country |= c - 'A' + 10; + } + } + + /* set default console region (USA > JAPAN > EUROPE) */ + if (country & 4) region_code = REGION_USA; + else if (country & 1) region_code = REGION_JAPAN_NTSC; + else if (country & 8) region_code = REGION_EUROPE; + else if (country & 2) region_code = REGION_JAPAN_PAL; + else region_code = REGION_USA; + + /* some games need specific region settings but have wrong header*/ + if (((strstr(rominfo.product,"T-45033") != NULL) && (rominfo.checksum == 0x0F81)) || /* Alisia Dragon (Europe) */ + (strstr(rominfo.product,"T-69046-50") != NULL) || /* Back to the Future III (Europe) */ + (strstr(rominfo.product,"T-120106-00") != NULL) || /* Brian Lara Cricket (Europe) */ + (strstr(rominfo.product,"T-70096 -00") != NULL)) /* Muhammad Ali Heavyweight Boxing (Europe) */ + { + /* need PAL settings */ + region_code = REGION_EUROPE; + } + else if ((rominfo.realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL)) + { + /* On Dal Jang Goon (Korea) needs JAPAN region code */ + region_code = REGION_JAPAN_NTSC; + } + } + + /* 8-bit cartridge */ + else + { + region_code = sms_cart_region_detect(); + } + + /* save auto-detected region */ + rom_region = region_code; + } + else + { + /* restore auto-detected region */ + region_code = rom_region; + } + + /* force console region if requested */ + if (config.region_detect == 1) region_code = REGION_USA; + else if (config.region_detect == 2) region_code = REGION_EUROPE; + else if (config.region_detect == 3) region_code = REGION_JAPAN_NTSC; + else if (config.region_detect == 4) region_code = REGION_JAPAN_PAL; + + /* autodetect PAL/NTSC timings */ + vdp_pal = (region_code >> 6) & 0x01; + + /* autodetect PAL/NTSC master clock */ + system_clock = vdp_pal ? MCLOCK_PAL : MCLOCK_NTSC; + + /* force PAL/NTSC timings if requested */ + if (config.vdp_mode == 1) vdp_pal = 0; + else if (config.vdp_mode == 2) vdp_pal = 1; + + /* force PAL/NTSC master clock if requested */ + if (config.master_clock == 1) system_clock = MCLOCK_NTSC; + else if (config.master_clock == 2) system_clock = MCLOCK_PAL; +} + + +/**************************************************************************** + * get_company (Softdev - 2006) + * + * Try to determine which company made this rom + * + * Ok, for some reason there's no standard for this. + * It seems that there can be pretty much anything you like following the + * copyright (C) symbol! + ****************************************************************************/ +char *get_company(void) +{ + char *s; + int i; + char company[10]; + + for (i = 3; i < 8; i++) + { + company[i - 3] = rominfo.copyright[i]; + } + company[5] = 0; + + /** OK, first look for a hyphen + * Capcom use T-12 for example + */ + s = strstr (company, "-"); + if (s != NULL) + { + s++; + strcpy (company, s); + } + + /** Strip any trailing spaces **/ + for (i = strlen (company) - 1; i >= 0; i--) + if (company[i] == 32) + company[i] = 0; + + if (strlen (company) == 0) + return (char *)companyinfo[MAXCOMPANY - 1].company; + + for (i = 0; i < MAXCOMPANY - 1; i++) + { + if (!(strncmp (company, companyinfo[i].companyid, strlen (company)))) + return (char *)companyinfo[i].company; + } + + return (char *)companyinfo[MAXCOMPANY - 1].company; +} + +/**************************************************************************** + * get_peripheral (Softdev - 2006) + * + * Return peripheral name based on header code + * + ****************************************************************************/ +char *get_peripheral(int index) +{ + if (index < MAXPERIPHERALS) + return (char *)peripheralinfo[index].pName; + return (char *)companyinfo[MAXCOMPANY - 1].company; +} + diff --git a/genplus-gx/core/loadrom.h b/genplus-gx/core/loadrom.h new file mode 100644 index 0000000000..5fad9f7584 --- /dev/null +++ b/genplus-gx/core/loadrom.h @@ -0,0 +1,75 @@ +/*************************************************************************************** + * Genesis Plus + * ROM Loading Support + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _LOADROM_H_ +#define _LOADROM_H_ + +#define MAXROMSIZE 10485760 + +typedef struct +{ + char consoletype[18]; /* Genesis or Mega Drive */ + char copyright[18]; /* Copyright message */ + char domestic[50]; /* Domestic name of ROM */ + char international[50]; /* International name of ROM */ + char ROMType[4]; /* Boot ROM (BR), Educational (AL) or Game (GM) program */ + char product[14]; /* Product serial number */ + unsigned short checksum; /* ROM Checksum (header) */ + unsigned short realchecksum; /* ROM Checksum (calculated) */ + unsigned int romstart; /* ROM start address */ + unsigned int romend; /* ROM end address */ + char country[18]; /* Country flag */ + uint16 peripherals; /* Supported peripherals */ +} ROMINFO; + + +/* Global variables */ +extern ROMINFO rominfo; +extern uint8 romtype; + +/* Function prototypes */ +extern int load_bios(void); +extern int load_rom(char *filename); +extern void get_region(char *romheader); +extern char *get_company(void); +extern char *get_peripheral(int index); +extern void getrominfo(char *romheader); + +#endif /* _LOADROM_H_ */ + diff --git a/genplus-gx/core/m68k/m68k.h b/genplus-gx/core/m68k/m68k.h new file mode 100644 index 0000000000..f93b3fc0e3 --- /dev/null +++ b/genplus-gx/core/m68k/m68k.h @@ -0,0 +1,389 @@ +#ifndef M68K__HEADER +#define M68K__HEADER + +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 3.32 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright Karl Stenerud. All rights reserved. + * + * This code may be freely used for non-commercial purposes as long as this + * copyright notice remains unaltered in the source code and any binary files + * containing this code in compiled form. + * + * All other licensing terms must be negotiated with the author + * (Karl Stenerud). + * + * The latest version of this code can be obtained at: + * http://kstenerud.cjb.net + */ + + /* Modified by Eke-Eke for Genesis Plus GX: + + - removed unused stuff to reduce memory usage / optimize execution (multiple CPU types support, NMI support, ...) + - moved stuff to compile statically in a single object file + - implemented support for global cycle count (shared by 68k & Z80 CPU) + - added support for interrupt latency (Sesame's Street Counting Cafe, Fatal Rewind) + - added proper cycle use on reset + - added cycle accurate timings for MUL/DIV instructions (thanks to Jorge Cwik !) + - fixed undocumented flags for DIV instructions (Blood Shot) + - added MAIN-CPU & SUB-CPU support for Mega CD emulation + + */ + +/* ======================================================================== */ +/* ================================ INCLUDES ============================== */ +/* ======================================================================== */ + +#include +#include "macros.h" + +/* ======================================================================== */ +/* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */ +/* ======================================================================== */ + +/* Check for > 32bit sizes */ +#if UINT_MAX > 0xffffffff + #define M68K_INT_GT_32_BIT 1 +#else + #define M68K_INT_GT_32_BIT 0 +#endif + +/* Data types used in this emulation core */ +#undef sint8 +#undef sint16 +#undef sint32 +#undef sint64 +#undef uint8 +#undef uint16 +#undef uint32 +#undef uint64 +#undef sint +#undef uint + +#define sint8 signed char /* ASG: changed from char to signed char */ +#define sint16 signed short +#define sint32 signed int /* AWJ: changed from long to int */ +#define uint8 unsigned char +#define uint16 unsigned short +#define uint32 unsigned int /* AWJ: changed from long to int */ + +/* signed and unsigned int must be at least 32 bits wide */ +#define sint signed int +#define uint unsigned int + + +#if M68K_USE_64_BIT +#define sint64 signed long long +#define uint64 unsigned long long +#else +#define sint64 sint32 +#define uint64 uint32 +#endif /* M68K_USE_64_BIT */ + + + +/* Allow for architectures that don't have 8-bit sizes */ +/*#if UCHAR_MAX == 0xff*/ + #define MAKE_INT_8(A) (sint8)(A) +/*#else + #undef sint8 + #define sint8 signed int + #undef uint8 + #define uint8 unsigned int + INLINE sint MAKE_INT_8(uint value) + { + return (value & 0x80) ? value | ~0xff : value & 0xff; + }*/ +/*#endif *//* UCHAR_MAX == 0xff */ + + +/* Allow for architectures that don't have 16-bit sizes */ +/*#if USHRT_MAX == 0xffff*/ + #define MAKE_INT_16(A) (sint16)(A) +/*#else + #undef sint16 + #define sint16 signed int + #undef uint16 + #define uint16 unsigned int + INLINE sint MAKE_INT_16(uint value) + { + return (value & 0x8000) ? value | ~0xffff : value & 0xffff; + }*/ +/*#endif *//* USHRT_MAX == 0xffff */ + + +/* Allow for architectures that don't have 32-bit sizes */ +/*#if UINT_MAX == 0xffffffff*/ + #define MAKE_INT_32(A) (sint32)(A) +/*#else + #undef sint32 + #define sint32 signed int + #undef uint32 + #define uint32 unsigned int + INLINE sint MAKE_INT_32(uint value) + { + return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff; + }*/ +/*#endif *//* UINT_MAX == 0xffffffff */ + + + +/* ======================================================================== */ +/* ============================ GENERAL DEFINES =========================== */ + +/* ======================================================================== */ + +/* There are 7 levels of interrupt to the 68K. + * A transition from < 7 to 7 will cause a non-maskable interrupt (NMI). + */ +#define M68K_IRQ_NONE 0 +#define M68K_IRQ_1 1 +#define M68K_IRQ_2 2 +#define M68K_IRQ_3 3 +#define M68K_IRQ_4 4 +#define M68K_IRQ_5 5 +#define M68K_IRQ_6 6 +#define M68K_IRQ_7 7 + + +/* Special interrupt acknowledge values. + * Use these as special returns from the interrupt acknowledge callback + * (specified later in this header). + */ + +/* Causes an interrupt autovector (0x18 + interrupt level) to be taken. + * This happens in a real 68K if VPA or AVEC is asserted during an interrupt + * acknowledge cycle instead of DTACK. + */ +#define M68K_INT_ACK_AUTOVECTOR 0xffffffff + +/* Causes the spurious interrupt vector (0x18) to be taken + * This happens in a real 68K if BERR is asserted during the interrupt + * acknowledge cycle (i.e. no devices responded to the acknowledge). + */ +#define M68K_INT_ACK_SPURIOUS 0xfffffffe + + +/* Registers used by m68k_get_reg() and m68k_set_reg() */ +typedef enum +{ + /* Real registers */ + M68K_REG_D0, /* Data registers */ + M68K_REG_D1, + M68K_REG_D2, + M68K_REG_D3, + M68K_REG_D4, + M68K_REG_D5, + M68K_REG_D6, + M68K_REG_D7, + M68K_REG_A0, /* Address registers */ + M68K_REG_A1, + M68K_REG_A2, + M68K_REG_A3, + M68K_REG_A4, + M68K_REG_A5, + M68K_REG_A6, + M68K_REG_A7, + M68K_REG_PC, /* Program Counter */ + M68K_REG_SR, /* Status Register */ + M68K_REG_SP, /* The current Stack Pointer (located in A7) */ + M68K_REG_USP, /* User Stack Pointer */ + M68K_REG_ISP, /* Interrupt Stack Pointer */ + +#if M68K_EMULATE_PREFETCH + /* Assumed registers */ + /* These are cheat registers which emulate the 1-longword prefetch + * present in the 68000 and 68010. + */ + M68K_REG_PREF_ADDR, /* Last prefetch address */ + M68K_REG_PREF_DATA, /* Last prefetch data */ +#endif + + /* Convenience registers */ + M68K_REG_IR /* Instruction register */ +} m68k_register_t; + + +/* 68k memory map structure */ +typedef struct +{ + unsigned char *base; /* memory-based access (ROM, RAM) */ + unsigned int (*read8)(unsigned int address); /* I/O byte read access */ + unsigned int (*read16)(unsigned int address); /* I/O word read access */ + void (*write8)(unsigned int address, unsigned int data); /* I/O byte write access */ + void (*write16)(unsigned int address, unsigned int data); /* I/O word write access */ +} cpu_memory_map; + +/* 68k idle loop detection */ +typedef struct +{ + uint pc; + uint cycle; + uint detected; +} cpu_idle_t; + +typedef struct +{ + cpu_memory_map memory_map[256]; /* memory mapping */ + + cpu_idle_t poll; /* polling detection */ + + uint cycles; /* current master cycle count */ + uint cycle_end; /* aimed master cycle count for current execution frame */ + + uint dar[16]; /* Data and Address Registers */ + uint pc; /* Program Counter */ + uint sp[5]; /* User and Interrupt Stack Pointers */ + uint ir; /* Instruction Register */ + uint t1_flag; /* Trace 1 */ + uint s_flag; /* Supervisor */ + uint x_flag; /* Extend */ + uint n_flag; /* Negative */ + uint not_z_flag; /* Zero, inverted for speedups */ + uint v_flag; /* Overflow */ + uint c_flag; /* Carry */ + uint int_mask; /* I0-I2 */ + uint int_level; /* State of interrupt pins IPL0-IPL2 -- ASG: changed from ints_pending */ + uint stopped; /* Stopped state */ + + uint pref_addr; /* Last prefetch address */ + uint pref_data; /* Data in the prefetch queue */ + + uint instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */ + uint run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */ + uint aerr_enabled; /* Enables/deisables address error checks at runtime */ + jmp_buf aerr_trap; /* Address error jump */ + uint aerr_address; /* Address error location */ + uint aerr_write_mode; /* Address error write mode */ + uint aerr_fc; /* Address error FC code */ + + uint tracing; /* Tracing enable flag */ + + uint address_space; /* Current FC code */ + + /* Callbacks to host */ + int (*int_ack_callback)(int int_line); /* Interrupt Acknowledge */ + void (*reset_instr_callback)(void); /* Called when a RESET instruction is encountered */ + int (*tas_instr_callback)(void); /* Called when a TAS instruction is encountered, allows / disallows writeback */ + void (*set_fc_callback)(unsigned int new_fc); /* Called when the CPU function code changes */ +} m68ki_cpu_core; + +/* CPU cores */ +extern m68ki_cpu_core m68k; +extern m68ki_cpu_core s68k; + + +/* ======================================================================== */ +/* ============================== CALLBACKS =============================== */ +/* ======================================================================== */ + +/* These functions allow you to set callbacks to the host when specific events + * occur. Note that you must enable the corresponding value in m68kconf.h + * in order for these to do anything useful. + * Note: I have defined default callbacks which are used if you have enabled + * the corresponding #define in m68kconf.h but either haven't assigned a + * callback or have assigned a callback of NULL. + */ + +#if M68K_EMULATE_INT_ACK == OPT_ON +/* Set the callback for an interrupt acknowledge. + * You must enable M68K_EMULATE_INT_ACK in m68kconf.h. + * The CPU will call the callback with the interrupt level being acknowledged. + * The host program must return either a vector from 0x02-0xff, or one of the + * special interrupt acknowledge values specified earlier in this header. + * If this is not implemented, the CPU will always assume an autovectored + * interrupt, and will automatically clear the interrupt request when it + * services the interrupt. + * Default behavior: return M68K_INT_ACK_AUTOVECTOR. + */ +void m68k_set_int_ack_callback(int (*callback)(int int_level)); +#endif + +#if M68K_EMULATE_RESET == OPT_ON +/* Set the callback for the RESET instruction. + * You must enable M68K_EMULATE_RESET in m68kconf.h. + * The CPU calls this callback every time it encounters a RESET instruction. + * Default behavior: do nothing. + */ +void m68k_set_reset_instr_callback(void (*callback)(void)); +#endif + +#if M68K_TAS_HAS_CALLBACK == OPT_ON +/* Set the callback for the TAS instruction. + * You must enable M68K_TAS_HAS_CALLBACK in m68kconf.h. + * The CPU calls this callback every time it encounters a TAS instruction. + * Default behavior: return 1, allow writeback. + */ +void m68k_set_tas_instr_callback(int (*callback)(void)); +#endif + +#if M68K_EMULATE_FC == OPT_ON +/* Set the callback for CPU function code changes. + * You must enable M68K_EMULATE_FC in m68kconf.h. + * The CPU calls this callback with the function code before every memory + * access to set the CPU's function code according to what kind of memory + * access it is (supervisor/user, program/data and such). + * Default behavior: do nothing. + */ +void m68k_set_fc_callback(void (*callback)(unsigned int new_fc)); +#endif + + +/* ======================================================================== */ +/* ====================== FUNCTIONS TO ACCESS THE CPU ===================== */ +/* ======================================================================== */ + +/* Do whatever initialisations the core requires. Should be called + * at least once at init time. + */ +extern void m68k_init(void); +extern void s68k_init(void); + +/* Pulse the RESET pin on the CPU. + * You *MUST* reset the CPU at least once to initialize the emulation + */ +extern void m68k_pulse_reset(void); +extern void s68k_pulse_reset(void); + +/* Run until given cycle count is reached */ +extern void m68k_run(unsigned int cycles); +extern void s68k_run(unsigned int cycles); + +/* Set the IPL0-IPL2 pins on the CPU (IRQ). + * A transition from < 7 to 7 will cause a non-maskable interrupt (NMI). + * Setting IRQ to 0 will clear an interrupt request. + */ +extern void m68k_set_irq(unsigned int int_level); +extern void m68k_set_irq_delay(unsigned int int_level); +extern void m68k_update_irq(unsigned int mask); +extern void s68k_update_irq(unsigned int mask); + +/* Halt the CPU as if you pulsed the HALT pin. */ +extern void m68k_pulse_halt(void); +extern void m68k_clear_halt(void); +extern void s68k_pulse_halt(void); +extern void s68k_clear_halt(void); + + +/* Peek at the internals of a CPU context. This can either be a context + * retrieved using m68k_get_context() or the currently running context. + * If context is NULL, the currently running CPU context will be used. + */ +extern unsigned int m68k_get_reg(m68k_register_t reg); +extern unsigned int s68k_get_reg(m68k_register_t reg); + +/* Poke values into the internals of the currently running CPU context */ +extern void m68k_set_reg(m68k_register_t reg, unsigned int value); +extern void s68k_set_reg(m68k_register_t reg, unsigned int value); + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + +#endif /* M68K__HEADER */ diff --git a/genplus-gx/core/m68k/m68kconf.h b/genplus-gx/core/m68k/m68kconf.h new file mode 100644 index 0000000000..dd59133ddb --- /dev/null +++ b/genplus-gx/core/m68k/m68kconf.h @@ -0,0 +1,93 @@ +#ifndef M68KCONF__HEADER +#define M68KCONF__HEADER + +/* ======================================================================== */ +/* ======================== MAIN 68K CONFIGURATION ======================== */ +/* ======================================================================== */ + +/* Configuration switches. + * Use OPT_SPECIFY_HANDLER for configuration options that allow callbacks. + * OPT_SPECIFY_HANDLER causes the core to link directly to the function + * or macro you specify, rather than using callback functions whose pointer + * must be passed in using m68k_set_xxx_callback(). + */ +#define OPT_OFF 0 +#define OPT_ON 1 +#define OPT_SPECIFY_HANDLER 2 + +/* If ON, the CPU will call m68k_write_32_pd() when it executes move.l with a + * predecrement destination EA mode instead of m68k_write_32(). + * To simulate real 68k behavior, m68k_write_32_pd() must first write the high + * word to [address+2], and then write the low word to [address]. + */ +#define M68K_SIMULATE_PD_WRITES OPT_OFF + +/* If ON, CPU will call the interrupt acknowledge callback when it services an + * interrupt. + * If off, all interrupts will be autovectored and all interrupt requests will + * auto-clear when the interrupt is serviced. + */ +#define M68K_EMULATE_INT_ACK OPT_SPECIFY_HANDLER +#define M68K_INT_ACK_CALLBACK(A) vdp_68k_irq_ack(A) + +/* If ON, CPU will call the output reset callback when it encounters a reset + * instruction. + */ +#define M68K_EMULATE_RESET OPT_OFF +#define M68K_RESET_CALLBACK() your_reset_handler_function() + +/* If ON, CPU will call the callback when it encounters a tas + * instruction. + */ +#define M68K_TAS_HAS_CALLBACK OPT_OFF +#define M68K_TAS_CALLBACK() your_tas_handler_function() + +/* If ON, CPU will call the set fc callback on every memory access to + * differentiate between user/supervisor, program/data access like a real + * 68000 would. This should be enabled and the callback should be set if you + * want to properly emulate the m68010 or higher. (moves uses function codes + * to read/write data from different address spaces) + */ +#define M68K_EMULATE_FC OPT_OFF +#define M68K_SET_FC_CALLBACK(A) your_set_fc_handler_function(A) + +/* If ON, the CPU will monitor the trace flags and take trace exceptions + */ +#define M68K_EMULATE_TRACE OPT_OFF + +/* If ON, the CPU will emulate the 4-byte prefetch queue of a real 68000 */ +#define M68K_EMULATE_PREFETCH OPT_OFF + +/* If ON, the CPU will generate address error exceptions if it tries to + * access a word or longword at an odd address. + * NOTE: This is only emulated properly for 68000 mode. + */ +#define M68K_EMULATE_ADDRESS_ERROR OPT_ON + +/* If ON and previous option is also ON, address error exceptions will + also be checked when fetching instructions. Disabling this can help + speeding up emulation while still emulating address error exceptions + on other memory access if needed. + * NOTE: This is only emulated properly for 68000 mode. + */ +#define M68K_CHECK_PC_ADDRESS_ERROR OPT_OFF + + +/* ----------------------------- COMPATIBILITY ---------------------------- */ + +/* The following options set optimizations that violate the current ANSI + * standard, but will be compliant under the forthcoming C9X standard. + */ + + +/* If ON, the enulation core will use 64-bit integers to speed up some + * operations. +*/ +#define M68K_USE_64_BIT OPT_OFF + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + +#endif /* M68KCONF__HEADER */ diff --git a/genplus-gx/core/m68k/m68kcpu.c b/genplus-gx/core/m68k/m68kcpu.c new file mode 100644 index 0000000000..1b67409feb --- /dev/null +++ b/genplus-gx/core/m68k/m68kcpu.c @@ -0,0 +1,385 @@ +/* ======================================================================== */ +/* MAIN 68K CORE */ +/* ======================================================================== */ + +extern int vdp_68k_irq_ack(int int_level); + +#define m68ki_cpu m68k +#define MUL (7) + +/* ======================================================================== */ +/* ================================ INCLUDES ============================== */ +/* ======================================================================== */ + +#ifndef BUILD_TABLES +#include "m68ki_cycles.h" +#endif + +#include "m68kconf.h" +#include "m68kcpu.h" +#include "m68kops.h" + +/* ======================================================================== */ +/* ================================= DATA ================================= */ +/* ======================================================================== */ + +#ifdef BUILD_TABLES +static unsigned char m68ki_cycles[0x10000]; +#endif + +static int irq_latency; + +m68ki_cpu_core m68k; + + +/* ======================================================================== */ +/* =============================== CALLBACKS ============================== */ +/* ======================================================================== */ + +/* Default callbacks used if the callback hasn't been set yet, or if the + * callback is set to NULL + */ + +#if M68K_EMULATE_INT_ACK == OPT_ON +/* Interrupt acknowledge */ +static int default_int_ack_callback(int int_level) +{ + CPU_INT_LEVEL = 0; + return M68K_INT_ACK_AUTOVECTOR; +} +#endif + +#if M68K_EMULATE_RESET == OPT_ON +/* Called when a reset instruction is executed */ +static void default_reset_instr_callback(void) +{ +} +#endif + +#if M68K_TAS_HAS_CALLBACK == OPT_ON +/* Called when a tas instruction is executed */ +static int default_tas_instr_callback(void) +{ + return 1; // allow writeback +} +#endif + +#if M68K_EMULATE_FC == OPT_ON +/* Called every time there's bus activity (read/write to/from memory */ +static void default_set_fc_callback(unsigned int new_fc) +{ +} +#endif + + +/* ======================================================================== */ +/* ================================= API ================================== */ +/* ======================================================================== */ + +/* Access the internals of the CPU */ +unsigned int m68k_get_reg(m68k_register_t regnum) +{ + switch(regnum) + { + case M68K_REG_D0: return m68ki_cpu.dar[0]; + case M68K_REG_D1: return m68ki_cpu.dar[1]; + case M68K_REG_D2: return m68ki_cpu.dar[2]; + case M68K_REG_D3: return m68ki_cpu.dar[3]; + case M68K_REG_D4: return m68ki_cpu.dar[4]; + case M68K_REG_D5: return m68ki_cpu.dar[5]; + case M68K_REG_D6: return m68ki_cpu.dar[6]; + case M68K_REG_D7: return m68ki_cpu.dar[7]; + case M68K_REG_A0: return m68ki_cpu.dar[8]; + case M68K_REG_A1: return m68ki_cpu.dar[9]; + case M68K_REG_A2: return m68ki_cpu.dar[10]; + case M68K_REG_A3: return m68ki_cpu.dar[11]; + case M68K_REG_A4: return m68ki_cpu.dar[12]; + case M68K_REG_A5: return m68ki_cpu.dar[13]; + case M68K_REG_A6: return m68ki_cpu.dar[14]; + case M68K_REG_A7: return m68ki_cpu.dar[15]; + case M68K_REG_PC: return MASK_OUT_ABOVE_32(m68ki_cpu.pc); + case M68K_REG_SR: return m68ki_cpu.t1_flag | + (m68ki_cpu.s_flag << 11) | + m68ki_cpu.int_mask | + ((m68ki_cpu.x_flag & XFLAG_SET) >> 4) | + ((m68ki_cpu.n_flag & NFLAG_SET) >> 4) | + ((!m68ki_cpu.not_z_flag) << 2) | + ((m68ki_cpu.v_flag & VFLAG_SET) >> 6) | + ((m68ki_cpu.c_flag & CFLAG_SET) >> 8); + case M68K_REG_SP: return m68ki_cpu.dar[15]; + case M68K_REG_USP: return m68ki_cpu.s_flag ? m68ki_cpu.sp[0] : m68ki_cpu.dar[15]; + case M68K_REG_ISP: return m68ki_cpu.s_flag ? m68ki_cpu.dar[15] : m68ki_cpu.sp[4]; +#if M68K_EMULATE_PREFETCH + case M68K_REG_PREF_ADDR: return m68ki_cpu.pref_addr; + case M68K_REG_PREF_DATA: return m68ki_cpu.pref_data; +#endif + case M68K_REG_IR: return m68ki_cpu.ir; + default: return 0; + } +} + +void m68k_set_reg(m68k_register_t regnum, unsigned int value) +{ + switch(regnum) + { + case M68K_REG_D0: REG_D[0] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D1: REG_D[1] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D2: REG_D[2] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D3: REG_D[3] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D4: REG_D[4] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D5: REG_D[5] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D6: REG_D[6] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D7: REG_D[7] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A0: REG_A[0] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A1: REG_A[1] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A2: REG_A[2] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A3: REG_A[3] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A4: REG_A[4] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A5: REG_A[5] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A6: REG_A[6] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A7: REG_A[7] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_PC: m68ki_jump(MASK_OUT_ABOVE_32(value)); return; + case M68K_REG_SR: m68ki_set_sr(value); return; + case M68K_REG_SP: REG_SP = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_USP: if(FLAG_S) + REG_USP = MASK_OUT_ABOVE_32(value); + else + REG_SP = MASK_OUT_ABOVE_32(value); + return; + case M68K_REG_ISP: if(FLAG_S) + REG_SP = MASK_OUT_ABOVE_32(value); + else + REG_ISP = MASK_OUT_ABOVE_32(value); + return; + case M68K_REG_IR: REG_IR = MASK_OUT_ABOVE_16(value); return; +#if M68K_EMULATE_PREFETCH + case M68K_REG_PREF_ADDR: CPU_PREF_ADDR = MASK_OUT_ABOVE_32(value); return; +#endif + default: return; + } +} + +/* Set the callbacks */ +#if M68K_EMULATE_INT_ACK == OPT_ON +void m68k_set_int_ack_callback(int (*callback)(int int_level)) +{ + CALLBACK_INT_ACK = callback ? callback : default_int_ack_callback; +} +#endif + +#if M68K_EMULATE_RESET == OPT_ON +void m68k_set_reset_instr_callback(void (*callback)(void)) +{ + CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback; +} +#endif + +#if M68K_TAS_HAS_CALLBACK == OPT_ON +void m68k_set_tas_instr_callback(int (*callback)(void)) +{ + CALLBACK_TAS_INSTR = callback ? callback : default_tas_instr_callback; +} +#endif + +#if M68K_EMULATE_FC == OPT_ON +void m68k_set_fc_callback(void (*callback)(unsigned int new_fc)) +{ + CALLBACK_SET_FC = callback ? callback : default_set_fc_callback; +} +#endif + +#ifdef LOGVDP +extern void error(char *format, ...); +extern uint16 v_counter; +#endif + +/* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */ +/* KS: Modified so that IPL* bits match with mask positions in the SR + * and cleaned out remenants of the interrupt controller. + */ +void m68k_update_irq(unsigned int mask) +{ + /* Update IRQ level */ + CPU_INT_LEVEL |= (mask << 8); + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] IRQ Level = %d(0x%02x) (%x)\n", v_counter, m68k.cycles/3420, m68k.cycles, m68k.cycles%3420,CPU_INT_LEVEL>>8,FLAG_INT_MASK,m68k_get_reg(M68K_REG_PC)); +#endif +} + +void m68k_set_irq(unsigned int int_level) +{ + /* Set IRQ level */ + CPU_INT_LEVEL = int_level << 8; + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] IRQ Level = %d(0x%02x) (%x)\n", v_counter, m68k.cycles/3420, m68k.cycles, m68k.cycles%3420,CPU_INT_LEVEL>>8,FLAG_INT_MASK,m68k_get_reg(M68K_REG_PC)); +#endif +} + +/* IRQ latency (Fatal Rewind, Sesame's Street Counting Cafe)*/ +void m68k_set_irq_delay(unsigned int int_level) +{ + /* Prevent reentrance */ + if (!irq_latency) + { + /* This is always triggered from MOVE instructions (VDP CTRL port write) */ + /* We just make sure this is not a MOVE.L instruction as we could be in */ + /* the middle of its execution (first memory write). */ + if ((REG_IR & 0xF000) != 0x2000) + { + /* Finish executing current instruction */ + USE_CYCLES(CYC_INSTRUCTION[REG_IR]); + + /* One instruction delay before interrupt */ + irq_latency = 1; + m68ki_trace_t1() /* auto-disable (see m68kcpu.h) */ + m68ki_use_data_space() /* auto-disable (see m68kcpu.h) */ + REG_IR = m68ki_read_imm_16(); + m68ki_instruction_jump_table[REG_IR](); + m68ki_exception_if_trace() /* auto-disable (see m68kcpu.h) */ + irq_latency = 0; + } + + /* Set IRQ level */ + CPU_INT_LEVEL = int_level << 8; + } + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] IRQ Level = %d(0x%02x) (%x)\n", v_counter, m68k.cycles/3420, m68k.cycles, m68k.cycles%3420,CPU_INT_LEVEL>>8,FLAG_INT_MASK,m68k_get_reg(M68K_REG_PC)); +#endif + + /* Check interrupt mask to process IRQ */ + m68ki_check_interrupts(); /* Level triggered (IRQ) */ +} + +void m68k_run(unsigned int cycles) +{ + /* Make sure CPU is not already ahead */ + if (m68k.cycles >= cycles) + { + return; + } + + /* Check interrupt mask to process IRQ if needed */ + m68ki_check_interrupts(); + + /* Make sure we're not stopped */ + if (CPU_STOPPED) + { + m68k.cycles = cycles; + return; + } + + /* Save end cycles count for when CPU is stopped */ + m68k.cycle_end = cycles; + + /* Return point for when we have an address error (TODO: use goto) */ + m68ki_set_address_error_trap() /* auto-disable (see m68kcpu.h) */ + +#ifdef LOGVDP + error("[%d][%d] m68k run to %d cycles (%x), irq mask = %x (%x)\n", v_counter, m68k.cycles, cycles, m68k.pc,FLAG_INT_MASK, CPU_INT_LEVEL); +#endif + + while (m68k.cycles < cycles) + { + /* Set tracing accodring to T1. */ + m68ki_trace_t1() /* auto-disable (see m68kcpu.h) */ + + /* Set the address space for reads */ + m68ki_use_data_space() /* auto-disable (see m68kcpu.h) */ + + /* Decode next instruction */ + REG_IR = m68ki_read_imm_16(); + + /* Execute instruction */ + m68ki_instruction_jump_table[REG_IR](); + USE_CYCLES(CYC_INSTRUCTION[REG_IR]); + + /* Trace m68k_exception, if necessary */ + m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */ + } +} + +void m68k_init(void) +{ +#ifdef BUILD_TABLES + static uint emulation_initialized = 0; + + /* The first call to this function initializes the opcode handler jump table */ + if(!emulation_initialized) + { + m68ki_build_opcode_table(); + emulation_initialized = 1; + } +#endif + +#if M68K_EMULATE_INT_ACK == OPT_ON + m68k_set_int_ack_callback(NULL); +#endif +#if M68K_EMULATE_RESET == OPT_ON + m68k_set_reset_instr_callback(NULL); +#endif +#if M68K_TAS_HAS_CALLBACK == OPT_ON + m68k_set_tas_instr_callback(NULL); +#endif +#if M68K_EMULATE_FC == OPT_ON + m68k_set_fc_callback(NULL); +#endif +} + +/* Pulse the RESET line on the CPU */ +void m68k_pulse_reset(void) +{ + /* Clear all stop levels */ + CPU_STOPPED = 0; +#if M68K_EMULATE_ADDRESS_ERROR + CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; +#endif + + /* Turn off tracing */ + FLAG_T1 = 0; + m68ki_clear_trace() + + /* Interrupt mask to level 7 */ + FLAG_INT_MASK = 0x0700; + CPU_INT_LEVEL = 0; + irq_latency = 0; + + /* Go to supervisor mode */ + m68ki_set_s_flag(SFLAG_SET); + + /* Invalidate the prefetch queue */ +#if M68K_EMULATE_PREFETCH + /* Set to arbitrary number since our first fetch is from 0 */ + CPU_PREF_ADDR = 0x1000; +#endif /* M68K_EMULATE_PREFETCH */ + + /* Read the initial stack pointer and program counter */ + m68ki_jump(0); + REG_SP = m68ki_read_imm_32(); + REG_PC = m68ki_read_imm_32(); + m68ki_jump(REG_PC); + +#if M68K_EMULATE_ADDRESS_ERROR + CPU_RUN_MODE = RUN_MODE_NORMAL; +#endif + + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_RESET]); +} + +void m68k_pulse_halt(void) +{ + /* Pulse the HALT line on the CPU */ + CPU_STOPPED |= STOP_LEVEL_HALT; +} + +void m68k_clear_halt(void) +{ + /* Clear the HALT line on the CPU */ + CPU_STOPPED &= ~STOP_LEVEL_HALT; +} + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ diff --git a/genplus-gx/core/m68k/m68kcpu.h b/genplus-gx/core/m68k/m68kcpu.h new file mode 100644 index 0000000000..317f2cdd12 --- /dev/null +++ b/genplus-gx/core/m68k/m68kcpu.h @@ -0,0 +1,1415 @@ +#ifndef M68KCPU__HEADER +#define M68KCPU__HEADER + +/* ======================================================================== */ +/* GENERIC 68K CORE */ +/* ======================================================================== */ + +#include +#include +#include + +#if M68K_EMULATE_ADDRESS_ERROR +#include +#endif /* M68K_EMULATE_ADDRESS_ERROR */ + +#include "m68k.h" + + +/* ======================================================================== */ +/* ============================ GENERAL DEFINES =========================== */ +/* ======================================================================== */ + +/* Exception Vectors handled by emulation */ +#define EXCEPTION_RESET 0 +#define EXCEPTION_BUS_ERROR 2 /* This one is not emulated! */ +#define EXCEPTION_ADDRESS_ERROR 3 /* This one is partially emulated (doesn't stack a proper frame yet) */ +#define EXCEPTION_ILLEGAL_INSTRUCTION 4 +#define EXCEPTION_ZERO_DIVIDE 5 +#define EXCEPTION_CHK 6 +#define EXCEPTION_TRAPV 7 +#define EXCEPTION_PRIVILEGE_VIOLATION 8 +#define EXCEPTION_TRACE 9 +#define EXCEPTION_1010 10 +#define EXCEPTION_1111 11 +#define EXCEPTION_FORMAT_ERROR 14 +#define EXCEPTION_UNINITIALIZED_INTERRUPT 15 +#define EXCEPTION_SPURIOUS_INTERRUPT 24 +#define EXCEPTION_INTERRUPT_AUTOVECTOR 24 +#define EXCEPTION_TRAP_BASE 32 + +/* Function codes set by CPU during data/address bus activity */ +#define FUNCTION_CODE_USER_DATA 1 +#define FUNCTION_CODE_USER_PROGRAM 2 +#define FUNCTION_CODE_SUPERVISOR_DATA 5 +#define FUNCTION_CODE_SUPERVISOR_PROGRAM 6 +#define FUNCTION_CODE_CPU_SPACE 7 + +/* Different ways to stop the CPU */ +#define STOP_LEVEL_STOP 1 +#define STOP_LEVEL_HALT 2 + +/* Used for 68000 address error processing */ +#if M68K_EMULATE_ADDRESS_ERROR +#define INSTRUCTION_YES 0 +#define INSTRUCTION_NO 0x08 +#define MODE_READ 0x10 +#define MODE_WRITE 0 + +#define RUN_MODE_NORMAL 0 +#define RUN_MODE_BERR_AERR_RESET 1 +#endif + +#ifndef NULL +#define NULL ((void*)0) +#endif + +/* ======================================================================== */ +/* ================================ MACROS ================================ */ +/* ======================================================================== */ + + +/* ---------------------------- General Macros ---------------------------- */ + +/* Bit Isolation Macros */ +#define BIT_0(A) ((A) & 0x00000001) +#define BIT_1(A) ((A) & 0x00000002) +#define BIT_2(A) ((A) & 0x00000004) +#define BIT_3(A) ((A) & 0x00000008) +#define BIT_4(A) ((A) & 0x00000010) +#define BIT_5(A) ((A) & 0x00000020) +#define BIT_6(A) ((A) & 0x00000040) +#define BIT_7(A) ((A) & 0x00000080) +#define BIT_8(A) ((A) & 0x00000100) +#define BIT_9(A) ((A) & 0x00000200) +#define BIT_A(A) ((A) & 0x00000400) +#define BIT_B(A) ((A) & 0x00000800) +#define BIT_C(A) ((A) & 0x00001000) +#define BIT_D(A) ((A) & 0x00002000) +#define BIT_E(A) ((A) & 0x00004000) +#define BIT_F(A) ((A) & 0x00008000) +#define BIT_10(A) ((A) & 0x00010000) +#define BIT_11(A) ((A) & 0x00020000) +#define BIT_12(A) ((A) & 0x00040000) +#define BIT_13(A) ((A) & 0x00080000) +#define BIT_14(A) ((A) & 0x00100000) +#define BIT_15(A) ((A) & 0x00200000) +#define BIT_16(A) ((A) & 0x00400000) +#define BIT_17(A) ((A) & 0x00800000) +#define BIT_18(A) ((A) & 0x01000000) +#define BIT_19(A) ((A) & 0x02000000) +#define BIT_1A(A) ((A) & 0x04000000) +#define BIT_1B(A) ((A) & 0x08000000) +#define BIT_1C(A) ((A) & 0x10000000) +#define BIT_1D(A) ((A) & 0x20000000) +#define BIT_1E(A) ((A) & 0x40000000) +#define BIT_1F(A) ((A) & 0x80000000) + +/* Get the most significant bit for specific sizes */ +#define GET_MSB_8(A) ((A) & 0x80) +#define GET_MSB_9(A) ((A) & 0x100) +#define GET_MSB_16(A) ((A) & 0x8000) +#define GET_MSB_17(A) ((A) & 0x10000) +#define GET_MSB_32(A) ((A) & 0x80000000) +#if M68K_USE_64_BIT +#define GET_MSB_33(A) ((A) & 0x100000000) +#endif /* M68K_USE_64_BIT */ + +/* Isolate nibbles */ +#define LOW_NIBBLE(A) ((A) & 0x0f) +#define HIGH_NIBBLE(A) ((A) & 0xf0) + +/* These are used to isolate 8, 16, and 32 bit sizes */ +#define MASK_OUT_ABOVE_2(A) ((A) & 3) +#define MASK_OUT_ABOVE_8(A) ((A) & 0xff) +#define MASK_OUT_ABOVE_16(A) ((A) & 0xffff) +#define MASK_OUT_BELOW_2(A) ((A) & ~3) +#define MASK_OUT_BELOW_8(A) ((A) & ~0xff) +#define MASK_OUT_BELOW_16(A) ((A) & ~0xffff) + +/* No need to mask if we are 32 bit */ +#if M68K_INT_GT_32_BIT || M68K_USE_64_BIT + #define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff) + #define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff) +#else + #define MASK_OUT_ABOVE_32(A) (A) + #define MASK_OUT_BELOW_32(A) 0 +#endif /* M68K_INT_GT_32_BIT || M68K_USE_64_BIT */ + +/* Simulate address lines of 68k family */ +#define ADDRESS_68K(A) ((A)&CPU_ADDRESS_MASK) + + +/* Shift & Rotate Macros. */ +#define LSL(A, C) ((A) << (C)) +#define LSR(A, C) ((A) >> (C)) + +/* Some > 32-bit optimizations */ +#if M68K_INT_GT_32_BIT + /* Shift left and right */ + #define LSR_32(A, C) ((A) >> (C)) + #define LSL_32(A, C) ((A) << (C)) +#else + /* We have to do this because the morons at ANSI decided that shifts + * by >= data size are undefined. + */ + #define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0) + #define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0) +#endif /* M68K_INT_GT_32_BIT */ + +#if M68K_USE_64_BIT + #define LSL_32_64(A, C) ((A) << (C)) + #define LSR_32_64(A, C) ((A) >> (C)) + #define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C))) + #define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C))) +#endif /* M68K_USE_64_BIT */ + +#define ROL_8(A, C) MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C))) +#define ROL_9(A, C) (LSL(A, C) | LSR(A, 9-(C))) +#define ROL_16(A, C) MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C))) +#define ROL_17(A, C) (LSL(A, C) | LSR(A, 17-(C))) +#define ROL_32(A, C) MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C))) +#define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C))) + +#define ROR_8(A, C) MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C))) +#define ROR_9(A, C) (LSR(A, C) | LSL(A, 9-(C))) +#define ROR_16(A, C) MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C))) +#define ROR_17(A, C) (LSR(A, C) | LSL(A, 17-(C))) +#define ROR_32(A, C) MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C))) +#define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C))) + + + +/* ------------------------------ CPU Access ------------------------------ */ + +/* Access the CPU registers */ +#define REG_DA m68ki_cpu.dar /* easy access to data and address regs */ +#define REG_D m68ki_cpu.dar +#define REG_A (m68ki_cpu.dar+8) +#define REG_PC m68ki_cpu.pc +#define REG_SP_BASE m68ki_cpu.sp +#define REG_USP m68ki_cpu.sp[0] +#define REG_ISP m68ki_cpu.sp[4] +#define REG_SP m68ki_cpu.dar[15] +#define REG_IR m68ki_cpu.ir + +#define FLAG_T1 m68ki_cpu.t1_flag +#define FLAG_S m68ki_cpu.s_flag +#define FLAG_X m68ki_cpu.x_flag +#define FLAG_N m68ki_cpu.n_flag +#define FLAG_Z m68ki_cpu.not_z_flag +#define FLAG_V m68ki_cpu.v_flag +#define FLAG_C m68ki_cpu.c_flag +#define FLAG_INT_MASK m68ki_cpu.int_mask + +#define CPU_INT_LEVEL m68ki_cpu.int_level /* ASG: changed from CPU_INTS_PENDING */ +#define CPU_STOPPED m68ki_cpu.stopped +#if M68K_EMULATE_PREFETCH +#define CPU_PREF_ADDR m68ki_cpu.pref_addr +#define CPU_PREF_DATA m68ki_cpu.pref_data +#endif +#define CPU_ADDRESS_MASK 0x00ffffff +#if M68K_EMULATE_ADDRESS_ERROR +#define CPU_INSTR_MODE m68ki_cpu.instr_mode +#define CPU_RUN_MODE m68ki_cpu.run_mode +#endif + +#define CYC_INSTRUCTION m68ki_cycles +#define CYC_EXCEPTION m68ki_exception_cycle_table +#define CYC_BCC_NOTAKE_B ( -2 * MUL) +#define CYC_BCC_NOTAKE_W ( 2 * MUL) +#define CYC_DBCC_F_NOEXP ( -2 * MUL) +#define CYC_DBCC_F_EXP ( 2 * MUL) +#define CYC_SCC_R_TRUE ( 2 * MUL) +#define CYC_MOVEM_W ( 4 * MUL) +#define CYC_MOVEM_L ( 8 * MUL) +#define CYC_SHIFT ( 2 * MUL) +#define CYC_RESET (132 * MUL) + +#if M68K_EMULATE_INT_ACK == OPT_ON +#define CALLBACK_INT_ACK m68ki_cpu.int_ack_callback +#endif +#if M68K_EMULATE_RESET == OPT_ON +#define CALLBACK_RESET_INSTR m68ki_cpu.reset_instr_callback +#endif +#if M68K_TAS_HAS_CALLBACK == OPT_ON +#define CALLBACK_TAS_INSTR m68ki_cpu.tas_instr_callback +#endif +#if M68K_EMULATE_FC == OPT_ON +#define CALLBACK_SET_FC m68ki_cpu.set_fc_callback +#endif + + +/* ----------------------------- Configuration ---------------------------- */ + +/* These defines are dependant on the configuration defines in m68kconf.h */ + +/* Enable or disable callback functions */ +#if M68K_EMULATE_INT_ACK + #if M68K_EMULATE_INT_ACK == OPT_SPECIFY_HANDLER + #define m68ki_int_ack(A) M68K_INT_ACK_CALLBACK(A); + #else + #define m68ki_int_ack(A) CALLBACK_INT_ACK(A); + #endif +#else + /* Default action is to used autovector mode, which is most common */ + #define m68ki_int_ack(A) M68K_INT_ACK_AUTOVECTOR +#endif /* M68K_EMULATE_INT_ACK */ + +#if M68K_EMULATE_RESET + #if M68K_EMULATE_RESET == OPT_SPECIFY_HANDLER + #define m68ki_output_reset() M68K_RESET_CALLBACK(); + #else + #define m68ki_output_reset() CALLBACK_RESET_INSTR(); + #endif +#else + #define m68ki_output_reset() +#endif /* M68K_EMULATE_RESET */ + +#if M68K_TAS_HAS_CALLBACK + #if M68K_TAS_HAS_CALLBACK == OPT_SPECIFY_HANDLER + #define m68ki_tas_callback() M68K_TAS_CALLBACK() + #else + #define m68ki_tas_callback() CALLBACK_TAS_INSTR() + #endif +#else + #define m68ki_tas_callback() 0 +#endif /* M68K_TAS_HAS_CALLBACK */ + + +/* Enable or disable function code emulation */ +#if M68K_EMULATE_FC + #if M68K_EMULATE_FC == OPT_SPECIFY_HANDLER + #define m68ki_set_fc(A) M68K_SET_FC_CALLBACK(A); + #else + #define m68ki_set_fc(A) CALLBACK_SET_FC(A); + #endif + #define m68ki_use_data_space() m68ki_cpu.address_space = FUNCTION_CODE_USER_DATA; + #define m68ki_use_program_space() m68ki_cpu.address_space = FUNCTION_CODE_USER_PROGRAM; + #define m68ki_get_address_space() m68ki_cpu.address_space +#else + #define m68ki_set_fc(A) + #define m68ki_use_data_space() + #define m68ki_use_program_space() + #define m68ki_get_address_space() FUNCTION_CODE_USER_DATA +#endif /* M68K_EMULATE_FC */ + + +/* Enable or disable trace emulation */ +#if M68K_EMULATE_TRACE + /* Initiates trace checking before each instruction (t1) */ + #define m68ki_trace_t1() m68ki_cpu.tracing = FLAG_T1; + /* Clear all tracing */ + #define m68ki_clear_trace() m68ki_cpu.tracing = 0; + /* Cause a trace exception if we are tracing */ + #define m68ki_exception_if_trace() if(m68ki_cpu.tracing) m68ki_exception_trace(); +#else + #define m68ki_trace_t1() + #define m68ki_clear_trace() + #define m68ki_exception_if_trace() +#endif /* M68K_EMULATE_TRACE */ + + +/* Enable or disable Address error emulation */ +#if M68K_EMULATE_ADDRESS_ERROR + #define m68ki_set_address_error_trap() \ + if(setjmp(m68ki_cpu.aerr_trap) != 0) \ + { \ + m68ki_exception_address_error(); \ + } + + #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) \ + if((ADDR)&1) \ + { \ + if (m68ki_cpu.aerr_enabled) \ + { \ + m68ki_cpu.aerr_address = ADDR; \ + m68ki_cpu.aerr_write_mode = WRITE_MODE; \ + m68ki_cpu.aerr_fc = FC; \ + longjmp(m68ki_cpu.aerr_trap, 1); \ + } \ + } +#else + #define m68ki_set_address_error_trap() + #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) +#endif /* M68K_ADDRESS_ERROR */ + + +/* -------------------------- EA / Operand Access ------------------------- */ + +/* + * The general instruction format follows this pattern: + * .... XXX. .... .YYY + * where XXX is register X and YYY is register Y + */ + +/* Data Register Isolation */ +#define DX (REG_D[(REG_IR >> 9) & 7]) +#define DY (REG_D[REG_IR & 7]) + +/* Address Register Isolation */ +#define AX (REG_A[(REG_IR >> 9) & 7]) +#define AY (REG_A[REG_IR & 7]) + +/* Effective Address Calculations */ +#define EA_AY_AI_8() AY /* address register indirect */ +#define EA_AY_AI_16() EA_AY_AI_8() +#define EA_AY_AI_32() EA_AY_AI_8() +#define EA_AY_PI_8() (AY++) /* postincrement (size = byte) */ +#define EA_AY_PI_16() ((AY+=2)-2) /* postincrement (size = word) */ +#define EA_AY_PI_32() ((AY+=4)-4) /* postincrement (size = long) */ +#define EA_AY_PD_8() (--AY) /* predecrement (size = byte) */ +#define EA_AY_PD_16() (AY-=2) /* predecrement (size = word) */ +#define EA_AY_PD_32() (AY-=4) /* predecrement (size = long) */ +#define EA_AY_DI_8() (AY+MAKE_INT_16(m68ki_read_imm_16())) /* displacement */ +#define EA_AY_DI_16() EA_AY_DI_8() +#define EA_AY_DI_32() EA_AY_DI_8() +#define EA_AY_IX_8() m68ki_get_ea_ix(AY) /* indirect + index */ +#define EA_AY_IX_16() EA_AY_IX_8() +#define EA_AY_IX_32() EA_AY_IX_8() + +#define EA_AX_AI_8() AX +#define EA_AX_AI_16() EA_AX_AI_8() +#define EA_AX_AI_32() EA_AX_AI_8() +#define EA_AX_PI_8() (AX++) +#define EA_AX_PI_16() ((AX+=2)-2) +#define EA_AX_PI_32() ((AX+=4)-4) +#define EA_AX_PD_8() (--AX) +#define EA_AX_PD_16() (AX-=2) +#define EA_AX_PD_32() (AX-=4) +#define EA_AX_DI_8() (AX+MAKE_INT_16(m68ki_read_imm_16())) +#define EA_AX_DI_16() EA_AX_DI_8() +#define EA_AX_DI_32() EA_AX_DI_8() +#define EA_AX_IX_8() m68ki_get_ea_ix(AX) +#define EA_AX_IX_16() EA_AX_IX_8() +#define EA_AX_IX_32() EA_AX_IX_8() + +#define EA_A7_PI_8() ((REG_A[7]+=2)-2) +#define EA_A7_PD_8() (REG_A[7]-=2) + +#define EA_AW_8() MAKE_INT_16(m68ki_read_imm_16()) /* absolute word */ +#define EA_AW_16() EA_AW_8() +#define EA_AW_32() EA_AW_8() +#define EA_AL_8() m68ki_read_imm_32() /* absolute long */ +#define EA_AL_16() EA_AL_8() +#define EA_AL_32() EA_AL_8() +#define EA_PCDI_8() m68ki_get_ea_pcdi() /* pc indirect + displacement */ +#define EA_PCDI_16() EA_PCDI_8() +#define EA_PCDI_32() EA_PCDI_8() +#define EA_PCIX_8() m68ki_get_ea_pcix() /* pc indirect + index */ +#define EA_PCIX_16() EA_PCIX_8() +#define EA_PCIX_32() EA_PCIX_8() + + +#define OPER_I_8() m68ki_read_imm_8() +#define OPER_I_16() m68ki_read_imm_16() +#define OPER_I_32() m68ki_read_imm_32() + + +/* --------------------------- Status Register ---------------------------- */ + +/* Flag Calculation Macros */ +#define CFLAG_8(A) (A) +#define CFLAG_16(A) ((A)>>8) + +#if M68K_INT_GT_32_BIT + #define CFLAG_ADD_32(S, D, R) ((R)>>24) + #define CFLAG_SUB_32(S, D, R) ((R)>>24) +#else + #define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23) + #define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23) +#endif /* M68K_INT_GT_32_BIT */ + +#define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R)) +#define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8) +#define VFLAG_ADD_32(S, D, R) (((S^R) & (D^R))>>24) + +#define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D)) +#define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8) +#define VFLAG_SUB_32(S, D, R) (((S^D) & (R^D))>>24) + +#define NFLAG_8(A) (A) +#define NFLAG_16(A) ((A)>>8) +#define NFLAG_32(A) ((A)>>24) +#define NFLAG_64(A) ((A)>>56) + +#define ZFLAG_8(A) MASK_OUT_ABOVE_8(A) +#define ZFLAG_16(A) MASK_OUT_ABOVE_16(A) +#define ZFLAG_32(A) MASK_OUT_ABOVE_32(A) + + +/* Flag values */ +#define NFLAG_SET 0x80 +#define NFLAG_CLEAR 0 +#define CFLAG_SET 0x100 +#define CFLAG_CLEAR 0 +#define XFLAG_SET 0x100 +#define XFLAG_CLEAR 0 +#define VFLAG_SET 0x80 +#define VFLAG_CLEAR 0 +#define ZFLAG_SET 0 +#define ZFLAG_CLEAR 0xffffffff +#define SFLAG_SET 4 +#define SFLAG_CLEAR 0 + +/* Turn flag values into 1 or 0 */ +#define XFLAG_AS_1() ((FLAG_X>>8)&1) +#define NFLAG_AS_1() ((FLAG_N>>7)&1) +#define VFLAG_AS_1() ((FLAG_V>>7)&1) +#define ZFLAG_AS_1() (!FLAG_Z) +#define CFLAG_AS_1() ((FLAG_C>>8)&1) + + +/* Conditions */ +#define COND_CS() (FLAG_C&0x100) +#define COND_CC() (!COND_CS()) +#define COND_VS() (FLAG_V&0x80) +#define COND_VC() (!COND_VS()) +#define COND_NE() FLAG_Z +#define COND_EQ() (!COND_NE()) +#define COND_MI() (FLAG_N&0x80) +#define COND_PL() (!COND_MI()) +#define COND_LT() ((FLAG_N^FLAG_V)&0x80) +#define COND_GE() (!COND_LT()) +#define COND_HI() (COND_CC() && COND_NE()) +#define COND_LS() (COND_CS() || COND_EQ()) +#define COND_GT() (COND_GE() && COND_NE()) +#define COND_LE() (COND_LT() || COND_EQ()) + +/* Reversed conditions */ +#define COND_NOT_CS() COND_CC() +#define COND_NOT_CC() COND_CS() +#define COND_NOT_VS() COND_VC() +#define COND_NOT_VC() COND_VS() +#define COND_NOT_NE() COND_EQ() +#define COND_NOT_EQ() COND_NE() +#define COND_NOT_MI() COND_PL() +#define COND_NOT_PL() COND_MI() +#define COND_NOT_LT() COND_GE() +#define COND_NOT_GE() COND_LT() +#define COND_NOT_HI() COND_LS() +#define COND_NOT_LS() COND_HI() +#define COND_NOT_GT() COND_LE() +#define COND_NOT_LE() COND_GT() + +/* Not real conditions, but here for convenience */ +#define COND_XS() (FLAG_X&0x100) +#define COND_XC() (!COND_XS) + + +/* Get the condition code register */ +#define m68ki_get_ccr() ((COND_XS() >> 4) | \ + (COND_MI() >> 4) | \ + (COND_EQ() << 2) | \ + (COND_VS() >> 6) | \ + (COND_CS() >> 8)) + +/* Get the status register */ +#define m68ki_get_sr() ( FLAG_T1 | \ + (FLAG_S << 11) | \ + FLAG_INT_MASK | \ + m68ki_get_ccr()) + + + +/* ---------------------------- Cycle Counting ---------------------------- */ + +#define USE_CYCLES(A) m68ki_cpu.cycles += (A) +#define SET_CYCLES(A) m68ki_cpu.cycles = (A) + + +/* ----------------------------- Read / Write ----------------------------- */ + +/* Read data immediately following the PC */ +#define m68k_read_immediate_16(address) *(uint16 *)(m68ki_cpu.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) +#define m68k_read_immediate_32(address) (m68k_read_immediate_16(address) << 16) | (m68k_read_immediate_16(address+2)) + +/* Read data relative to the PC */ +#define m68k_read_pcrelative_8(address) READ_BYTE(m68ki_cpu.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) +#define m68k_read_pcrelative_16(address) m68k_read_immediate_16(address) +#define m68k_read_pcrelative_32(address) m68k_read_immediate_32(address) + +/* Read from the current address space */ +#define m68ki_read_8(A) m68ki_read_8_fc (A, FLAG_S | m68ki_get_address_space()) +#define m68ki_read_16(A) m68ki_read_16_fc(A, FLAG_S | m68ki_get_address_space()) +#define m68ki_read_32(A) m68ki_read_32_fc(A, FLAG_S | m68ki_get_address_space()) + +/* Write to the current data space */ +#define m68ki_write_8(A, V) m68ki_write_8_fc (A, FLAG_S | FUNCTION_CODE_USER_DATA, V) +#define m68ki_write_16(A, V) m68ki_write_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V) +#define m68ki_write_32(A, V) m68ki_write_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V) + +/* map read immediate 8 to read immediate 16 */ +#define m68ki_read_imm_8() MASK_OUT_ABOVE_8(m68ki_read_imm_16()) + +/* Map PC-relative reads */ +#define m68ki_read_pcrel_8(A) m68k_read_pcrelative_8(A) +#define m68ki_read_pcrel_16(A) m68k_read_pcrelative_16(A) +#define m68ki_read_pcrel_32(A) m68k_read_pcrelative_32(A) + +/* Read from the program space */ +#define m68ki_read_program_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) +#define m68ki_read_program_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) +#define m68ki_read_program_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) + +/* Read from the data space */ +#define m68ki_read_data_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) +#define m68ki_read_data_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) +#define m68ki_read_data_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) + + + +/* ======================================================================== */ +/* =============================== PROTOTYPES ============================= */ +/* ======================================================================== */ + +/* Used by shift & rotate instructions */ +static const uint8 m68ki_shift_8_table[65] = +{ + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff +}; + +static const uint16 m68ki_shift_16_table[65] = +{ + 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, + 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff +}; + +static const uint m68ki_shift_32_table[65] = +{ + 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, + 0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, + 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000, + 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, + 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8, + 0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff +}; + + +/* Number of clock cycles to use for exception processing. + * I used 4 for any vectors that are undocumented for processing times. + */ +static const uint16 m68ki_exception_cycle_table[256] = +{ + 40*MUL, /* 0: Reset - Initial Stack Pointer */ + 4*MUL, /* 1: Reset - Initial Program Counter */ + 50*MUL, /* 2: Bus Error (unemulated) */ + 50*MUL, /* 3: Address Error (unemulated) */ + 34*MUL, /* 4: Illegal Instruction */ + 38*MUL, /* 5: Divide by Zero -- ASG: changed from 42 */ + 40*MUL, /* 6: CHK -- ASG: chanaged from 44 */ + 34*MUL, /* 7: TRAPV */ + 34*MUL, /* 8: Privilege Violation */ + 34*MUL, /* 9: Trace */ + 4*MUL, /* 10: 1010 */ + 4*MUL, /* 11: 1111 */ + 4*MUL, /* 12: RESERVED */ + 4*MUL, /* 13: Coprocessor Protocol Violation (unemulated) */ + 4*MUL, /* 14: Format Error */ + 44*MUL, /* 15: Uninitialized Interrupt */ + 4*MUL, /* 16: RESERVED */ + 4*MUL, /* 17: RESERVED */ + 4*MUL, /* 18: RESERVED */ + 4*MUL, /* 19: RESERVED */ + 4*MUL, /* 20: RESERVED */ + 4*MUL, /* 21: RESERVED */ + 4*MUL, /* 22: RESERVED */ + 4*MUL, /* 23: RESERVED */ + 44*MUL, /* 24: Spurious Interrupt */ + 44*MUL, /* 25: Level 1 Interrupt Autovector */ + 44*MUL, /* 26: Level 2 Interrupt Autovector */ + 44*MUL, /* 27: Level 3 Interrupt Autovector */ + 44*MUL, /* 28: Level 4 Interrupt Autovector */ + 44*MUL, /* 29: Level 5 Interrupt Autovector */ + 44*MUL, /* 30: Level 6 Interrupt Autovector */ + 44*MUL, /* 31: Level 7 Interrupt Autovector */ + 34*MUL, /* 32: TRAP #0 -- ASG: chanaged from 38 */ + 34*MUL, /* 33: TRAP #1 */ + 34*MUL, /* 34: TRAP #2 */ + 34*MUL, /* 35: TRAP #3 */ + 34*MUL, /* 36: TRAP #4 */ + 34*MUL, /* 37: TRAP #5 */ + 34*MUL, /* 38: TRAP #6 */ + 34*MUL, /* 39: TRAP #7 */ + 34*MUL, /* 40: TRAP #8 */ + 34*MUL, /* 41: TRAP #9 */ + 34*MUL, /* 42: TRAP #10 */ + 34*MUL, /* 43: TRAP #11 */ + 34*MUL, /* 44: TRAP #12 */ + 34*MUL, /* 45: TRAP #13 */ + 34*MUL, /* 46: TRAP #14 */ + 34*MUL, /* 47: TRAP #15 */ + 4*MUL, /* 48: FP Branch or Set on Unknown Condition (unemulated) */ + 4*MUL, /* 49: FP Inexact Result (unemulated) */ + 4*MUL, /* 50: FP Divide by Zero (unemulated) */ + 4*MUL, /* 51: FP Underflow (unemulated) */ + 4*MUL, /* 52: FP Operand Error (unemulated) */ + 4*MUL, /* 53: FP Overflow (unemulated) */ + 4*MUL, /* 54: FP Signaling NAN (unemulated) */ + 4*MUL, /* 55: FP Unimplemented Data Type (unemulated) */ + 4*MUL, /* 56: MMU Configuration Error (unemulated) */ + 4*MUL, /* 57: MMU Illegal Operation Error (unemulated) */ + 4*MUL, /* 58: MMU Access Level Violation Error (unemulated) */ + 4*MUL, /* 59: RESERVED */ + 4*MUL, /* 60: RESERVED */ + 4*MUL, /* 61: RESERVED */ + 4*MUL, /* 62: RESERVED */ + 4*MUL, /* 63: RESERVED */ + /* 64-255: User Defined */ + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL +}; + +/* Read data immediately after the program counter */ +INLINE uint m68ki_read_imm_16(void); +INLINE uint m68ki_read_imm_32(void); + +/* Read data with specific function code */ +INLINE uint m68ki_read_8_fc (uint address, uint fc); +INLINE uint m68ki_read_16_fc (uint address, uint fc); +INLINE uint m68ki_read_32_fc (uint address, uint fc); + +/* Write data with specific function code */ +INLINE void m68ki_write_8_fc (uint address, uint fc, uint value); +INLINE void m68ki_write_16_fc(uint address, uint fc, uint value); +INLINE void m68ki_write_32_fc(uint address, uint fc, uint value); + +/* Indexed and PC-relative ea fetching */ +INLINE uint m68ki_get_ea_pcdi(void); +INLINE uint m68ki_get_ea_pcix(void); +INLINE uint m68ki_get_ea_ix(uint An); + +/* Operand fetching */ +INLINE uint OPER_AY_AI_8(void); +INLINE uint OPER_AY_AI_16(void); +INLINE uint OPER_AY_AI_32(void); +INLINE uint OPER_AY_PI_8(void); +INLINE uint OPER_AY_PI_16(void); +INLINE uint OPER_AY_PI_32(void); +INLINE uint OPER_AY_PD_8(void); +INLINE uint OPER_AY_PD_16(void); +INLINE uint OPER_AY_PD_32(void); +INLINE uint OPER_AY_DI_8(void); +INLINE uint OPER_AY_DI_16(void); +INLINE uint OPER_AY_DI_32(void); +INLINE uint OPER_AY_IX_8(void); +INLINE uint OPER_AY_IX_16(void); +INLINE uint OPER_AY_IX_32(void); + +INLINE uint OPER_AX_AI_8(void); +INLINE uint OPER_AX_AI_16(void); +INLINE uint OPER_AX_AI_32(void); +INLINE uint OPER_AX_PI_8(void); +INLINE uint OPER_AX_PI_16(void); +INLINE uint OPER_AX_PI_32(void); +INLINE uint OPER_AX_PD_8(void); +INLINE uint OPER_AX_PD_16(void); +INLINE uint OPER_AX_PD_32(void); +INLINE uint OPER_AX_DI_8(void); +INLINE uint OPER_AX_DI_16(void); +INLINE uint OPER_AX_DI_32(void); +INLINE uint OPER_AX_IX_8(void); +INLINE uint OPER_AX_IX_16(void); +INLINE uint OPER_AX_IX_32(void); + +INLINE uint OPER_A7_PI_8(void); +INLINE uint OPER_A7_PD_8(void); + +INLINE uint OPER_AW_8(void); +INLINE uint OPER_AW_16(void); +INLINE uint OPER_AW_32(void); +INLINE uint OPER_AL_8(void); +INLINE uint OPER_AL_16(void); +INLINE uint OPER_AL_32(void); +INLINE uint OPER_PCDI_8(void); +INLINE uint OPER_PCDI_16(void); +INLINE uint OPER_PCDI_32(void); +INLINE uint OPER_PCIX_8(void); +INLINE uint OPER_PCIX_16(void); +INLINE uint OPER_PCIX_32(void); + +/* Stack operations */ +INLINE void m68ki_push_16(uint value); +INLINE void m68ki_push_32(uint value); +INLINE uint m68ki_pull_16(void); +INLINE uint m68ki_pull_32(void); + +/* Program flow operations */ +INLINE void m68ki_jump(uint new_pc); +INLINE void m68ki_jump_vector(uint vector); +INLINE void m68ki_branch_8(uint offset); +INLINE void m68ki_branch_16(uint offset); +INLINE void m68ki_branch_32(uint offset); + +/* Status register operations. */ +INLINE void m68ki_set_s_flag(uint value); /* Only bit 2 of value should be set (i.e. 4 or 0) */ +INLINE void m68ki_set_ccr(uint value); /* set the condition code register */ +INLINE void m68ki_set_sr(uint value); /* set the status register */ + +/* Exception processing */ +INLINE uint m68ki_init_exception(void); /* Initial exception processing */ +INLINE void m68ki_stack_frame_3word(uint pc, uint sr); /* Stack various frame types */ +#if M68K_EMULATE_ADDRESS_ERROR +INLINE void m68ki_stack_frame_buserr(uint sr); +#endif +INLINE void m68ki_exception_trap(uint vector); +INLINE void m68ki_exception_trapN(uint vector); +#if M68K_EMULATE_TRACE +INLINE void m68ki_exception_trace(void); +#endif +static void m68ki_exception_privilege_violation(void); /* do not inline in order to reduce function size and allow inlining of read/write functions by the compile */ +INLINE void m68ki_exception_1010(void); +INLINE void m68ki_exception_1111(void); +INLINE void m68ki_exception_illegal(void); +#if M68K_EMULATE_ADDRESS_ERROR +INLINE void m68ki_exception_address_error(void); +#endif +INLINE void m68ki_exception_interrupt(uint int_level); +INLINE void m68ki_check_interrupts(void); /* ASG: check for interrupts */ + +/* ======================================================================== */ +/* =========================== UTILITY FUNCTIONS ========================== */ +/* ======================================================================== */ + + +/* ---------------------------- Read Immediate ---------------------------- */ + +/* Handles all immediate reads, does address error check, function code setting, + * and prefetching if they are enabled in m68kconf.h + */ +INLINE uint m68ki_read_imm_16(void) +{ + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#if M68K_CHECK_PC_ADDRESS_ERROR + m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#endif +#if M68K_EMULATE_PREFETCH + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) + { + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); + CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR); + } + REG_PC += 2; + return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3)); +#else + uint pc = REG_PC; + REG_PC += 2; + return m68k_read_immediate_16(pc); +#endif /* M68K_EMULATE_PREFETCH */ +} + +INLINE uint m68ki_read_imm_32(void) +{ +#if M68K_EMULATE_PREFETCH + uint temp_val; + + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#if M68K_CHECK_PC_ADDRESS_ERROR + m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#endif + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) + { + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); + CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR); + } + temp_val = CPU_PREF_DATA; + REG_PC += 2; + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) + { + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); + CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR); + temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16)); + } + REG_PC += 2; + + return temp_val; +#else + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#if M68K_CHECK_PC_ADDRESS_ERROR + m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#endif + uint pc = REG_PC; + REG_PC += 4; + return m68k_read_immediate_32(pc); +#endif /* M68K_EMULATE_PREFETCH */ +} + + + +/* ------------------------- Top level read/write ------------------------- */ + +/* Handles all memory accesses (except for immediate reads if they are + * configured to use separate functions in m68kconf.h). + * All memory accesses must go through these top level functions. + * These functions will also check for address error and set the function + * code if they are enabled in m68kconf.h. + */ +INLINE uint m68ki_read_8_fc(uint address, uint fc) +{ + cpu_memory_map *temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];; + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + + if (temp->read8) return (*temp->read8)(ADDRESS_68K(address)); + else return READ_BYTE(temp->base, (address) & 0xffff); +} + +INLINE uint m68ki_read_16_fc(uint address, uint fc) +{ + cpu_memory_map *temp; + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */ + + temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; + if (temp->read16) return (*temp->read16)(ADDRESS_68K(address)); + else return *(uint16 *)(temp->base + ((address) & 0xffff)); +} + +INLINE uint m68ki_read_32_fc(uint address, uint fc) +{ + cpu_memory_map *temp; + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */ + + temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; + if (temp->read16) return ((*temp->read16)(ADDRESS_68K(address)) << 16) | ((*temp->read16)(ADDRESS_68K(address + 2))); + else return m68k_read_immediate_32(address); +} + +INLINE void m68ki_write_8_fc(uint address, uint fc, uint value) +{ + cpu_memory_map *temp; + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + + temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; + if (temp->write8) (*temp->write8)(ADDRESS_68K(address),value); + else WRITE_BYTE(temp->base, (address) & 0xffff, value); +} + +INLINE void m68ki_write_16_fc(uint address, uint fc, uint value) +{ + cpu_memory_map *temp; + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */ + + temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; + if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value); + else *(uint16 *)(temp->base + ((address) & 0xffff)) = value; +} + +INLINE void m68ki_write_32_fc(uint address, uint fc, uint value) +{ + cpu_memory_map *temp; + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address, MODE_WRITE, fc) /* auto-disable (see m68kcpu.h) */ + + temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; + if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value>>16); + else *(uint16 *)(temp->base + ((address) & 0xffff)) = value >> 16; + + temp = &m68ki_cpu.memory_map[((address + 2)>>16)&0xff]; + if (temp->write16) (*temp->write16)(ADDRESS_68K(address+2),value&0xffff); + else *(uint16 *)(temp->base + ((address + 2) & 0xffff)) = value; +} + + +/* --------------------- Effective Address Calculation -------------------- */ + +/* The program counter relative addressing modes cause operands to be + * retrieved from program space, not data space. + */ +INLINE uint m68ki_get_ea_pcdi(void) +{ + uint old_pc = REG_PC; + m68ki_use_program_space() /* auto-disable */ + return old_pc + MAKE_INT_16(m68ki_read_imm_16()); +} + + +INLINE uint m68ki_get_ea_pcix(void) +{ + m68ki_use_program_space() /* auto-disable */ + return m68ki_get_ea_ix(REG_PC); +} + +/* Indexed addressing modes are encoded as follows: + * + * Base instruction format: + * F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0 + * x x x x x x x x x x | 1 1 0 | BASE REGISTER (An) + * + * Base instruction format for destination EA in move instructions: + * F E D C | B A 9 | 8 7 6 | 5 4 3 2 1 0 + * x x x x | BASE REG | 1 1 0 | X X X X X X (An) + * + * Brief extension format: + * F | E D C | B | A 9 | 8 | 7 6 5 4 3 2 1 0 + * D/A | REGISTER | W/L | SCALE | 0 | DISPLACEMENT + * + * Full extension format: + * F E D C B A 9 8 7 6 5 4 3 2 1 0 + * D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS + * BASE DISPLACEMENT (0, 16, 32 bit) (bd) + * OUTER DISPLACEMENT (0, 16, 32 bit) (od) + * + * D/A: 0 = Dn, 1 = An (Xn) + * W/L: 0 = W (sign extend), 1 = L (.SIZE) + * SCALE: 00=1, 01=2, 10=4, 11=8 (*SCALE) + * BS: 0=add base reg, 1=suppress base reg (An suppressed) + * IS: 0=add index, 1=suppress index (Xn suppressed) + * BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long (size of bd) + * + * IS I/IS Operation + * 0 000 No Memory Indirect + * 0 001 indir prex with null outer + * 0 010 indir prex with word outer + * 0 011 indir prex with long outer + * 0 100 reserved + * 0 101 indir postx with null outer + * 0 110 indir postx with word outer + * 0 111 indir postx with long outer + * 1 000 no memory indirect + * 1 001 mem indir with null outer + * 1 010 mem indir with word outer + * 1 011 mem indir with long outer + * 1 100-111 reserved + */ +INLINE uint m68ki_get_ea_ix(uint An) +{ + /* An = base register */ + uint extension = m68ki_read_imm_16(); + + uint Xn = 0; /* Index register */ + + /* Calculate index */ + Xn = REG_DA[extension>>12]; /* Xn */ + if(!BIT_B(extension)) /* W/L */ + Xn = MAKE_INT_16(Xn); + + /* Add base register and displacement and return */ + return An + Xn + MAKE_INT_8(extension); +} + + +/* Fetch operands */ +INLINE uint OPER_AY_AI_8(void) {uint ea = EA_AY_AI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_PI_8(void) {uint ea = EA_AY_PI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_PD_8(void) {uint ea = EA_AY_PD_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_DI_8(void) {uint ea = EA_AY_DI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_IX_8(void) {uint ea = EA_AY_IX_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);} + +INLINE uint OPER_AX_AI_8(void) {uint ea = EA_AX_AI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_PI_8(void) {uint ea = EA_AX_PI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_PD_8(void) {uint ea = EA_AX_PD_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_DI_8(void) {uint ea = EA_AX_DI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_IX_8(void) {uint ea = EA_AX_IX_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);} + +INLINE uint OPER_A7_PI_8(void) {uint ea = EA_A7_PI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_A7_PD_8(void) {uint ea = EA_A7_PD_8(); return m68ki_read_8(ea); } + +INLINE uint OPER_AW_8(void) {uint ea = EA_AW_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AW_16(void) {uint ea = EA_AW_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AW_32(void) {uint ea = EA_AW_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AL_8(void) {uint ea = EA_AL_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AL_16(void) {uint ea = EA_AL_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AL_32(void) {uint ea = EA_AL_32(); return m68ki_read_32(ea);} +INLINE uint OPER_PCDI_8(void) {uint ea = EA_PCDI_8(); return m68ki_read_pcrel_8(ea); } +INLINE uint OPER_PCDI_16(void) {uint ea = EA_PCDI_16(); return m68ki_read_pcrel_16(ea);} +INLINE uint OPER_PCDI_32(void) {uint ea = EA_PCDI_32(); return m68ki_read_pcrel_32(ea);} +INLINE uint OPER_PCIX_8(void) {uint ea = EA_PCIX_8(); return m68ki_read_pcrel_8(ea); } +INLINE uint OPER_PCIX_16(void) {uint ea = EA_PCIX_16(); return m68ki_read_pcrel_16(ea);} +INLINE uint OPER_PCIX_32(void) {uint ea = EA_PCIX_32(); return m68ki_read_pcrel_32(ea);} + + + +/* ---------------------------- Stack Functions --------------------------- */ + +/* Push/pull data from the stack */ +/* Optimized access assuming stack is always located in ROM/RAM [EkeEke] */ +INLINE void m68ki_push_16(uint value) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); + /*m68ki_write_16(REG_SP, value);*/ + *(uint16 *)(m68ki_cpu.memory_map[(REG_SP>>16)&0xff].base + (REG_SP & 0xffff)) = value; +} + +INLINE void m68ki_push_32(uint value) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); + /*m68ki_write_32(REG_SP, value);*/ + *(uint16 *)(m68ki_cpu.memory_map[(REG_SP>>16)&0xff].base + (REG_SP & 0xffff)) = value >> 16; + *(uint16 *)(m68ki_cpu.memory_map[((REG_SP + 2)>>16)&0xff].base + ((REG_SP + 2) & 0xffff)) = value & 0xffff; +} + +INLINE uint m68ki_pull_16(void) +{ + uint sp = REG_SP; + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); + return m68k_read_immediate_16(sp); + /*return m68ki_read_16(sp);*/ +} + +INLINE uint m68ki_pull_32(void) +{ + uint sp = REG_SP; + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); + return m68k_read_immediate_32(sp); + /*return m68ki_read_32(sp);*/ +} + + + +/* ----------------------------- Program Flow ----------------------------- */ + +/* Jump to a new program location or vector. + * These functions will also call the pc_changed callback if it was enabled + * in m68kconf.h. + */ +INLINE void m68ki_jump(uint new_pc) +{ + REG_PC = new_pc; +} + +INLINE void m68ki_jump_vector(uint vector) +{ + REG_PC = m68ki_read_data_32(vector<<2); +} + + +/* Branch to a new memory location. + * The 32-bit branch will call pc_changed if it was enabled in m68kconf.h. + * So far I've found no problems with not calling pc_changed for 8 or 16 + * bit branches. + */ +INLINE void m68ki_branch_8(uint offset) +{ + REG_PC += MAKE_INT_8(offset); +} + +INLINE void m68ki_branch_16(uint offset) +{ + REG_PC += MAKE_INT_16(offset); +} + +INLINE void m68ki_branch_32(uint offset) +{ + REG_PC += offset; +} + + + +/* ---------------------------- Status Register --------------------------- */ + +/* Set the S flag and change the active stack pointer. + * Note that value MUST be 4 or 0. + */ +INLINE void m68ki_set_s_flag(uint value) +{ + /* Backup the old stack pointer */ + REG_SP_BASE[FLAG_S] = REG_SP; + /* Set the S flag */ + FLAG_S = value; + /* Set the new stack pointer */ + REG_SP = REG_SP_BASE[FLAG_S]; +} + + +/* Set the condition code register */ +INLINE void m68ki_set_ccr(uint value) +{ + FLAG_X = BIT_4(value) << 4; + FLAG_N = BIT_3(value) << 4; + FLAG_Z = !BIT_2(value); + FLAG_V = BIT_1(value) << 6; + FLAG_C = BIT_0(value) << 8; +} + + +/* Set the status register and check for interrupts */ +INLINE void m68ki_set_sr(uint value) +{ + /* Set the status register */ + FLAG_T1 = BIT_F(value); + FLAG_INT_MASK = value & 0x0700; + m68ki_set_ccr(value); + m68ki_set_s_flag((value >> 11) & 4); + + /* Check current IRQ status */ + m68ki_check_interrupts(); +} + + +/* ------------------------- Exception Processing ------------------------- */ + +/* Initiate exception processing */ +INLINE uint m68ki_init_exception(void) +{ + /* Save the old status register */ + uint sr = m68ki_get_sr(); + + /* Turn off trace flag, clear pending traces */ + FLAG_T1 = 0; + m68ki_clear_trace() + + /* Enter supervisor mode */ + m68ki_set_s_flag(SFLAG_SET); + + return sr; +} + +/* 3 word stack frame (68000 only) */ +INLINE void m68ki_stack_frame_3word(uint pc, uint sr) +{ + m68ki_push_32(pc); + m68ki_push_16(sr); +} + +#if M68K_EMULATE_ADDRESS_ERROR +/* Bus error stack frame (68000 only). + */ +INLINE void m68ki_stack_frame_buserr(uint sr) +{ + m68ki_push_32(REG_PC); + m68ki_push_16(sr); + m68ki_push_16(REG_IR); + m68ki_push_32(m68ki_cpu.aerr_address); /* access address */ + /* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC + * R/W 0 = write, 1 = read + * I/N 0 = instruction, 1 = not + * FC 3-bit function code + */ + m68ki_push_16(m68ki_cpu.aerr_write_mode | CPU_INSTR_MODE | m68ki_cpu.aerr_fc); +} +#endif + +/* Used for Group 2 exceptions. + */ +INLINE void m68ki_exception_trap(uint vector) +{ + uint sr = m68ki_init_exception(); + + m68ki_stack_frame_3word(REG_PC, sr); + + m68ki_jump_vector(vector); + + /* Use up some clock cycles */ + USE_CYCLES(CYC_EXCEPTION[vector]); +} + +/* Trap#n stacks a 0 frame but behaves like group2 otherwise */ +INLINE void m68ki_exception_trapN(uint vector) +{ + uint sr = m68ki_init_exception(); + m68ki_stack_frame_3word(REG_PC, sr); + m68ki_jump_vector(vector); + + /* Use up some clock cycles */ + USE_CYCLES(CYC_EXCEPTION[vector]); +} + +#if M68K_EMULATE_TRACE +/* Exception for trace mode */ +INLINE void m68ki_exception_trace(void) +{ + uint sr = m68ki_init_exception(); + + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + CPU_INSTR_MODE = INSTRUCTION_NO; + #endif /* M68K_EMULATE_ADDRESS_ERROR */ + + m68ki_stack_frame_3word(REG_PC, sr); + m68ki_jump_vector(EXCEPTION_TRACE); + + /* Trace nullifies a STOP instruction */ + CPU_STOPPED &= ~STOP_LEVEL_STOP; + + /* Use up some clock cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]); +} +#endif + +/* Exception for privilege violation */ +static void m68ki_exception_privilege_violation(void) +{ + uint sr = m68ki_init_exception(); + + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + CPU_INSTR_MODE = INSTRUCTION_NO; + #endif /* M68K_EMULATE_ADDRESS_ERROR */ + + m68ki_stack_frame_3word(REG_PC-2, sr); + m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION); + + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]); +} + +/* Exception for A-Line instructions */ +INLINE void m68ki_exception_1010(void) +{ + uint sr = m68ki_init_exception(); + m68ki_stack_frame_3word(REG_PC-2, sr); + m68ki_jump_vector(EXCEPTION_1010); + + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]); +} + +/* Exception for F-Line instructions */ +INLINE void m68ki_exception_1111(void) +{ + uint sr = m68ki_init_exception(); + m68ki_stack_frame_3word(REG_PC-2, sr); + m68ki_jump_vector(EXCEPTION_1111); + + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]); +} + +/* Exception for illegal instructions */ +INLINE void m68ki_exception_illegal(void) +{ + uint sr = m68ki_init_exception(); + + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + CPU_INSTR_MODE = INSTRUCTION_NO; + #endif /* M68K_EMULATE_ADDRESS_ERROR */ + + m68ki_stack_frame_3word(REG_PC-2, sr); + m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION); + + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION[REG_IR]); +} + + +#if M68K_EMULATE_ADDRESS_ERROR +/* Exception for address error */ +INLINE void m68ki_exception_address_error(void) +{ + uint sr = m68ki_init_exception(); + + /* If we were processing a bus error, address error, or reset, + * this is a catastrophic failure. + * Halt the CPU + */ + if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET) + { + CPU_STOPPED = STOP_LEVEL_HALT; + SET_CYCLES(m68ki_cpu.cycle_end - CYC_INSTRUCTION[REG_IR]); + return; + } + CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; + + /* Note: This is implemented for 68000 only! */ + m68ki_stack_frame_buserr(sr); + + m68ki_jump_vector(EXCEPTION_ADDRESS_ERROR); + + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ADDRESS_ERROR] - CYC_INSTRUCTION[REG_IR]); +} +#endif + +/* Service an interrupt request and start exception processing */ +INLINE void m68ki_exception_interrupt(uint int_level) +{ + uint vector, sr, new_pc; + + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + CPU_INSTR_MODE = INSTRUCTION_NO; + #endif /* M68K_EMULATE_ADDRESS_ERROR */ + + /* Turn off the stopped state */ + CPU_STOPPED &= STOP_LEVEL_HALT; + + /* If we are halted, don't do anything */ + if(CPU_STOPPED) + return; + + /* Always use the autovectors. */ + vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level; + + /* Start exception processing */ + sr = m68ki_init_exception(); + + /* Set the interrupt mask to the level of the one being serviced */ + FLAG_INT_MASK = int_level<<8; + + /* Acknowledge the interrupt */ + m68ki_int_ack(int_level); + + /* Get the new PC */ + new_pc = m68ki_read_data_32(vector<<2); + + /* If vector is uninitialized, call the uninitialized interrupt vector */ + if(new_pc == 0) + new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2)); + + /* Generate a stack frame */ + m68ki_stack_frame_3word(REG_PC, sr); + + m68ki_jump(new_pc); + + /* Update cycle count now */ + USE_CYCLES(CYC_EXCEPTION[vector]); +} + +/* ASG: Check for interrupts */ +INLINE void m68ki_check_interrupts(void) +{ + if(CPU_INT_LEVEL > FLAG_INT_MASK) + m68ki_exception_interrupt(CPU_INT_LEVEL>>8); +} + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + +#endif /* M68KCPU__HEADER */ diff --git a/genplus-gx/core/m68k/m68ki_cycles.h b/genplus-gx/core/m68k/m68ki_cycles.h new file mode 100644 index 0000000000..7120652553 --- /dev/null +++ b/genplus-gx/core/m68k/m68ki_cycles.h @@ -0,0 +1,4099 @@ +static const unsigned char m68ki_cycles[0x10000] = +{ + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 20*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 20*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, + 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 32*7, 36*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 20*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 20*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, + 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 32*7, 36*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, + 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 32*7, 36*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, + 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 32*7, 36*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 20*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 0*7, 0*7, 20*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, + 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 32*7, 36*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 28*7, 32*7, 28*7, 30*7, 24*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 30*7, 34*7, 30*7, 32*7, 26*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 28*7, 32*7, 28*7, 30*7, 24*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 28*7, 32*7, 28*7, 30*7, 24*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 30*7, 34*7, 30*7, 32*7, 26*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, + 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 34*7, 32*7, 36*7, 32*7, 34*7, 28*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 28*7, 32*7, 28*7, 30*7, 24*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 30*7, 34*7, 30*7, 32*7, 26*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 28*7, 32*7, 28*7, 30*7, 24*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 30*7, 34*7, 30*7, 32*7, 26*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 28*7, 32*7, 28*7, 30*7, 24*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 30*7, 34*7, 30*7, 32*7, 26*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 28*7, 32*7, 28*7, 30*7, 24*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 30*7, 34*7, 30*7, 32*7, 26*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 28*7, 32*7, 28*7, 30*7, 24*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 30*7, 34*7, 30*7, 32*7, 26*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, + 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 28*7, 32*7, 28*7, 30*7, 24*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, + 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 28*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 32*7, 30*7, 34*7, 30*7, 32*7, 26*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 24*7, 26*7, 20*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 22*7, 24*7, 18*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 8*7, 12*7, 8*7, 12*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 8*7, 12*7, 8*7, 12*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 8*7, 12*7, 8*7, 12*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 20*7, 24*7, 20*7, 22*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 8*7, 12*7, 8*7, 12*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 16*7, 20*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 8*7, 12*7, 8*7, 12*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, + 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 22*7, 26*7, 0*7, 0*7, 4*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 8*7, 12*7, 8*7, 12*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 8*7, 12*7, 8*7, 12*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 0*7, 4*7, 4*7, 20*7, 0*7, 16*7, 4*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 18*7, 20*7, 18*7, 22*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 10*7, 12*7, 10*7, 14*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 8*7, 12*7, 8*7, 12*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 14*7, 18*7, 14*7, 16*7, 10*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 14*7, 18*7, 14*7, 16*7, 10*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 14*7, 18*7, 14*7, 16*7, 10*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 14*7, 18*7, 14*7, 16*7, 10*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 14*7, 18*7, 14*7, 16*7, 10*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 14*7, 18*7, 14*7, 16*7, 10*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 14*7, 18*7, 14*7, 16*7, 10*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 14*7, 18*7, 14*7, 16*7, 10*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 14*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 8*7, 12*7, 8*7, 10*7, 4*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 10*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 12*7, 16*7, 12*7, 14*7, 8*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 16*7, 18*7, 12*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, 30*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, + 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 22*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, 24*7, + 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 26*7, 24*7, 28*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, + 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, + 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 20*7, 18*7, 22*7, 18*7, 20*7, 16*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, 12*7, + 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 14*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, 16*7, + 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 18*7, 16*7, 20*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, 6*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, 8*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, 0*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, + 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, 4*7, +}; diff --git a/genplus-gx/core/m68k/m68ki_instruction_jump_table.h b/genplus-gx/core/m68k/m68ki_instruction_jump_table.h new file mode 100644 index 0000000000..a3dbc50ee5 --- /dev/null +++ b/genplus-gx/core/m68k/m68ki_instruction_jump_table.h @@ -0,0 +1,8195 @@ +static void (* const m68ki_instruction_jump_table[0x10000])(void) = +{ + m68k_op_ori_8_d, m68k_op_ori_8_d, m68k_op_ori_8_d, m68k_op_ori_8_d, m68k_op_ori_8_d, m68k_op_ori_8_d, m68k_op_ori_8_d, m68k_op_ori_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_ori_8_ai, m68k_op_ori_8_ai, m68k_op_ori_8_ai, m68k_op_ori_8_ai, m68k_op_ori_8_ai, m68k_op_ori_8_ai, m68k_op_ori_8_ai, m68k_op_ori_8_ai, + m68k_op_ori_8_pi, m68k_op_ori_8_pi, m68k_op_ori_8_pi, m68k_op_ori_8_pi, m68k_op_ori_8_pi, m68k_op_ori_8_pi, m68k_op_ori_8_pi, m68k_op_ori_8_pi7, + m68k_op_ori_8_pd, m68k_op_ori_8_pd, m68k_op_ori_8_pd, m68k_op_ori_8_pd, m68k_op_ori_8_pd, m68k_op_ori_8_pd, m68k_op_ori_8_pd, m68k_op_ori_8_pd7, + m68k_op_ori_8_di, m68k_op_ori_8_di, m68k_op_ori_8_di, m68k_op_ori_8_di, m68k_op_ori_8_di, m68k_op_ori_8_di, m68k_op_ori_8_di, m68k_op_ori_8_di, + m68k_op_ori_8_ix, m68k_op_ori_8_ix, m68k_op_ori_8_ix, m68k_op_ori_8_ix, m68k_op_ori_8_ix, m68k_op_ori_8_ix, m68k_op_ori_8_ix, m68k_op_ori_8_ix, + m68k_op_ori_8_aw, m68k_op_ori_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_ori_16_toc, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_ori_16_d, m68k_op_ori_16_d, m68k_op_ori_16_d, m68k_op_ori_16_d, m68k_op_ori_16_d, m68k_op_ori_16_d, m68k_op_ori_16_d, m68k_op_ori_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_ori_16_ai, m68k_op_ori_16_ai, m68k_op_ori_16_ai, m68k_op_ori_16_ai, m68k_op_ori_16_ai, m68k_op_ori_16_ai, m68k_op_ori_16_ai, m68k_op_ori_16_ai, + m68k_op_ori_16_pi, m68k_op_ori_16_pi, m68k_op_ori_16_pi, m68k_op_ori_16_pi, m68k_op_ori_16_pi, m68k_op_ori_16_pi, m68k_op_ori_16_pi, m68k_op_ori_16_pi, + m68k_op_ori_16_pd, m68k_op_ori_16_pd, m68k_op_ori_16_pd, m68k_op_ori_16_pd, m68k_op_ori_16_pd, m68k_op_ori_16_pd, m68k_op_ori_16_pd, m68k_op_ori_16_pd, + m68k_op_ori_16_di, m68k_op_ori_16_di, m68k_op_ori_16_di, m68k_op_ori_16_di, m68k_op_ori_16_di, m68k_op_ori_16_di, m68k_op_ori_16_di, m68k_op_ori_16_di, + m68k_op_ori_16_ix, m68k_op_ori_16_ix, m68k_op_ori_16_ix, m68k_op_ori_16_ix, m68k_op_ori_16_ix, m68k_op_ori_16_ix, m68k_op_ori_16_ix, m68k_op_ori_16_ix, + m68k_op_ori_16_aw, m68k_op_ori_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_ori_16_tos, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_ori_32_d, m68k_op_ori_32_d, m68k_op_ori_32_d, m68k_op_ori_32_d, m68k_op_ori_32_d, m68k_op_ori_32_d, m68k_op_ori_32_d, m68k_op_ori_32_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_ori_32_ai, m68k_op_ori_32_ai, m68k_op_ori_32_ai, m68k_op_ori_32_ai, m68k_op_ori_32_ai, m68k_op_ori_32_ai, m68k_op_ori_32_ai, m68k_op_ori_32_ai, + m68k_op_ori_32_pi, m68k_op_ori_32_pi, m68k_op_ori_32_pi, m68k_op_ori_32_pi, m68k_op_ori_32_pi, m68k_op_ori_32_pi, m68k_op_ori_32_pi, m68k_op_ori_32_pi, + m68k_op_ori_32_pd, m68k_op_ori_32_pd, m68k_op_ori_32_pd, m68k_op_ori_32_pd, m68k_op_ori_32_pd, m68k_op_ori_32_pd, m68k_op_ori_32_pd, m68k_op_ori_32_pd, + m68k_op_ori_32_di, m68k_op_ori_32_di, m68k_op_ori_32_di, m68k_op_ori_32_di, m68k_op_ori_32_di, m68k_op_ori_32_di, m68k_op_ori_32_di, m68k_op_ori_32_di, + m68k_op_ori_32_ix, m68k_op_ori_32_ix, m68k_op_ori_32_ix, m68k_op_ori_32_ix, m68k_op_ori_32_ix, m68k_op_ori_32_ix, m68k_op_ori_32_ix, m68k_op_ori_32_ix, + m68k_op_ori_32_aw, m68k_op_ori_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, + m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, + m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, + m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi7, + m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd7, + m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, + m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, + m68k_op_btst_8_r_aw, m68k_op_btst_8_r_al, m68k_op_btst_8_r_pcdi, m68k_op_btst_8_r_pcix, m68k_op_btst_8_r_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, + m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, + m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, + m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi7, + m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd7, + m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, + m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, + m68k_op_bchg_8_r_aw, m68k_op_bchg_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, + m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, + m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, + m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi7, + m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd7, + m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, + m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, + m68k_op_bclr_8_r_aw, m68k_op_bclr_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, + m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, + m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, + m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi7, + m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd7, + m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, + m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, + m68k_op_bset_8_r_aw, m68k_op_bset_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_andi_8_d, m68k_op_andi_8_d, m68k_op_andi_8_d, m68k_op_andi_8_d, m68k_op_andi_8_d, m68k_op_andi_8_d, m68k_op_andi_8_d, m68k_op_andi_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_andi_8_ai, m68k_op_andi_8_ai, m68k_op_andi_8_ai, m68k_op_andi_8_ai, m68k_op_andi_8_ai, m68k_op_andi_8_ai, m68k_op_andi_8_ai, m68k_op_andi_8_ai, + m68k_op_andi_8_pi, m68k_op_andi_8_pi, m68k_op_andi_8_pi, m68k_op_andi_8_pi, m68k_op_andi_8_pi, m68k_op_andi_8_pi, m68k_op_andi_8_pi, m68k_op_andi_8_pi7, + m68k_op_andi_8_pd, m68k_op_andi_8_pd, m68k_op_andi_8_pd, m68k_op_andi_8_pd, m68k_op_andi_8_pd, m68k_op_andi_8_pd, m68k_op_andi_8_pd, m68k_op_andi_8_pd7, + m68k_op_andi_8_di, m68k_op_andi_8_di, m68k_op_andi_8_di, m68k_op_andi_8_di, m68k_op_andi_8_di, m68k_op_andi_8_di, m68k_op_andi_8_di, m68k_op_andi_8_di, + m68k_op_andi_8_ix, m68k_op_andi_8_ix, m68k_op_andi_8_ix, m68k_op_andi_8_ix, m68k_op_andi_8_ix, m68k_op_andi_8_ix, m68k_op_andi_8_ix, m68k_op_andi_8_ix, + m68k_op_andi_8_aw, m68k_op_andi_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_andi_16_toc, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_andi_16_d, m68k_op_andi_16_d, m68k_op_andi_16_d, m68k_op_andi_16_d, m68k_op_andi_16_d, m68k_op_andi_16_d, m68k_op_andi_16_d, m68k_op_andi_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_andi_16_ai, m68k_op_andi_16_ai, m68k_op_andi_16_ai, m68k_op_andi_16_ai, m68k_op_andi_16_ai, m68k_op_andi_16_ai, m68k_op_andi_16_ai, m68k_op_andi_16_ai, + m68k_op_andi_16_pi, m68k_op_andi_16_pi, m68k_op_andi_16_pi, m68k_op_andi_16_pi, m68k_op_andi_16_pi, m68k_op_andi_16_pi, m68k_op_andi_16_pi, m68k_op_andi_16_pi, + m68k_op_andi_16_pd, m68k_op_andi_16_pd, m68k_op_andi_16_pd, m68k_op_andi_16_pd, m68k_op_andi_16_pd, m68k_op_andi_16_pd, m68k_op_andi_16_pd, m68k_op_andi_16_pd, + m68k_op_andi_16_di, m68k_op_andi_16_di, m68k_op_andi_16_di, m68k_op_andi_16_di, m68k_op_andi_16_di, m68k_op_andi_16_di, m68k_op_andi_16_di, m68k_op_andi_16_di, + m68k_op_andi_16_ix, m68k_op_andi_16_ix, m68k_op_andi_16_ix, m68k_op_andi_16_ix, m68k_op_andi_16_ix, m68k_op_andi_16_ix, m68k_op_andi_16_ix, m68k_op_andi_16_ix, + m68k_op_andi_16_aw, m68k_op_andi_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_andi_16_tos, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_andi_32_d, m68k_op_andi_32_d, m68k_op_andi_32_d, m68k_op_andi_32_d, m68k_op_andi_32_d, m68k_op_andi_32_d, m68k_op_andi_32_d, m68k_op_andi_32_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_andi_32_ai, m68k_op_andi_32_ai, m68k_op_andi_32_ai, m68k_op_andi_32_ai, m68k_op_andi_32_ai, m68k_op_andi_32_ai, m68k_op_andi_32_ai, m68k_op_andi_32_ai, + m68k_op_andi_32_pi, m68k_op_andi_32_pi, m68k_op_andi_32_pi, m68k_op_andi_32_pi, m68k_op_andi_32_pi, m68k_op_andi_32_pi, m68k_op_andi_32_pi, m68k_op_andi_32_pi, + m68k_op_andi_32_pd, m68k_op_andi_32_pd, m68k_op_andi_32_pd, m68k_op_andi_32_pd, m68k_op_andi_32_pd, m68k_op_andi_32_pd, m68k_op_andi_32_pd, m68k_op_andi_32_pd, + m68k_op_andi_32_di, m68k_op_andi_32_di, m68k_op_andi_32_di, m68k_op_andi_32_di, m68k_op_andi_32_di, m68k_op_andi_32_di, m68k_op_andi_32_di, m68k_op_andi_32_di, + m68k_op_andi_32_ix, m68k_op_andi_32_ix, m68k_op_andi_32_ix, m68k_op_andi_32_ix, m68k_op_andi_32_ix, m68k_op_andi_32_ix, m68k_op_andi_32_ix, m68k_op_andi_32_ix, + m68k_op_andi_32_aw, m68k_op_andi_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, + m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, + m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, + m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi7, + m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd7, + m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, + m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, + m68k_op_btst_8_r_aw, m68k_op_btst_8_r_al, m68k_op_btst_8_r_pcdi, m68k_op_btst_8_r_pcix, m68k_op_btst_8_r_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, + m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, + m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, + m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi7, + m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd7, + m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, + m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, + m68k_op_bchg_8_r_aw, m68k_op_bchg_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, + m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, + m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, + m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi7, + m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd7, + m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, + m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, + m68k_op_bclr_8_r_aw, m68k_op_bclr_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, + m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, + m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, + m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi7, + m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd7, + m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, + m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, + m68k_op_bset_8_r_aw, m68k_op_bset_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subi_8_d, m68k_op_subi_8_d, m68k_op_subi_8_d, m68k_op_subi_8_d, m68k_op_subi_8_d, m68k_op_subi_8_d, m68k_op_subi_8_d, m68k_op_subi_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subi_8_ai, m68k_op_subi_8_ai, m68k_op_subi_8_ai, m68k_op_subi_8_ai, m68k_op_subi_8_ai, m68k_op_subi_8_ai, m68k_op_subi_8_ai, m68k_op_subi_8_ai, + m68k_op_subi_8_pi, m68k_op_subi_8_pi, m68k_op_subi_8_pi, m68k_op_subi_8_pi, m68k_op_subi_8_pi, m68k_op_subi_8_pi, m68k_op_subi_8_pi, m68k_op_subi_8_pi7, + m68k_op_subi_8_pd, m68k_op_subi_8_pd, m68k_op_subi_8_pd, m68k_op_subi_8_pd, m68k_op_subi_8_pd, m68k_op_subi_8_pd, m68k_op_subi_8_pd, m68k_op_subi_8_pd7, + m68k_op_subi_8_di, m68k_op_subi_8_di, m68k_op_subi_8_di, m68k_op_subi_8_di, m68k_op_subi_8_di, m68k_op_subi_8_di, m68k_op_subi_8_di, m68k_op_subi_8_di, + m68k_op_subi_8_ix, m68k_op_subi_8_ix, m68k_op_subi_8_ix, m68k_op_subi_8_ix, m68k_op_subi_8_ix, m68k_op_subi_8_ix, m68k_op_subi_8_ix, m68k_op_subi_8_ix, + m68k_op_subi_8_aw, m68k_op_subi_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subi_16_d, m68k_op_subi_16_d, m68k_op_subi_16_d, m68k_op_subi_16_d, m68k_op_subi_16_d, m68k_op_subi_16_d, m68k_op_subi_16_d, m68k_op_subi_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subi_16_ai, m68k_op_subi_16_ai, m68k_op_subi_16_ai, m68k_op_subi_16_ai, m68k_op_subi_16_ai, m68k_op_subi_16_ai, m68k_op_subi_16_ai, m68k_op_subi_16_ai, + m68k_op_subi_16_pi, m68k_op_subi_16_pi, m68k_op_subi_16_pi, m68k_op_subi_16_pi, m68k_op_subi_16_pi, m68k_op_subi_16_pi, m68k_op_subi_16_pi, m68k_op_subi_16_pi, + m68k_op_subi_16_pd, m68k_op_subi_16_pd, m68k_op_subi_16_pd, m68k_op_subi_16_pd, m68k_op_subi_16_pd, m68k_op_subi_16_pd, m68k_op_subi_16_pd, m68k_op_subi_16_pd, + m68k_op_subi_16_di, m68k_op_subi_16_di, m68k_op_subi_16_di, m68k_op_subi_16_di, m68k_op_subi_16_di, m68k_op_subi_16_di, m68k_op_subi_16_di, m68k_op_subi_16_di, + m68k_op_subi_16_ix, m68k_op_subi_16_ix, m68k_op_subi_16_ix, m68k_op_subi_16_ix, m68k_op_subi_16_ix, m68k_op_subi_16_ix, m68k_op_subi_16_ix, m68k_op_subi_16_ix, + m68k_op_subi_16_aw, m68k_op_subi_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subi_32_d, m68k_op_subi_32_d, m68k_op_subi_32_d, m68k_op_subi_32_d, m68k_op_subi_32_d, m68k_op_subi_32_d, m68k_op_subi_32_d, m68k_op_subi_32_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subi_32_ai, m68k_op_subi_32_ai, m68k_op_subi_32_ai, m68k_op_subi_32_ai, m68k_op_subi_32_ai, m68k_op_subi_32_ai, m68k_op_subi_32_ai, m68k_op_subi_32_ai, + m68k_op_subi_32_pi, m68k_op_subi_32_pi, m68k_op_subi_32_pi, m68k_op_subi_32_pi, m68k_op_subi_32_pi, m68k_op_subi_32_pi, m68k_op_subi_32_pi, m68k_op_subi_32_pi, + m68k_op_subi_32_pd, m68k_op_subi_32_pd, m68k_op_subi_32_pd, m68k_op_subi_32_pd, m68k_op_subi_32_pd, m68k_op_subi_32_pd, m68k_op_subi_32_pd, m68k_op_subi_32_pd, + m68k_op_subi_32_di, m68k_op_subi_32_di, m68k_op_subi_32_di, m68k_op_subi_32_di, m68k_op_subi_32_di, m68k_op_subi_32_di, m68k_op_subi_32_di, m68k_op_subi_32_di, + m68k_op_subi_32_ix, m68k_op_subi_32_ix, m68k_op_subi_32_ix, m68k_op_subi_32_ix, m68k_op_subi_32_ix, m68k_op_subi_32_ix, m68k_op_subi_32_ix, m68k_op_subi_32_ix, + m68k_op_subi_32_aw, m68k_op_subi_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, + m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, + m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, + m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi7, + m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd7, + m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, + m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, + m68k_op_btst_8_r_aw, m68k_op_btst_8_r_al, m68k_op_btst_8_r_pcdi, m68k_op_btst_8_r_pcix, m68k_op_btst_8_r_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, + m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, + m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, + m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi7, + m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd7, + m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, + m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, + m68k_op_bchg_8_r_aw, m68k_op_bchg_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, + m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, + m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, + m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi7, + m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd7, + m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, + m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, + m68k_op_bclr_8_r_aw, m68k_op_bclr_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, + m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, + m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, + m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi7, + m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd7, + m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, + m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, + m68k_op_bset_8_r_aw, m68k_op_bset_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addi_8_d, m68k_op_addi_8_d, m68k_op_addi_8_d, m68k_op_addi_8_d, m68k_op_addi_8_d, m68k_op_addi_8_d, m68k_op_addi_8_d, m68k_op_addi_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addi_8_ai, m68k_op_addi_8_ai, m68k_op_addi_8_ai, m68k_op_addi_8_ai, m68k_op_addi_8_ai, m68k_op_addi_8_ai, m68k_op_addi_8_ai, m68k_op_addi_8_ai, + m68k_op_addi_8_pi, m68k_op_addi_8_pi, m68k_op_addi_8_pi, m68k_op_addi_8_pi, m68k_op_addi_8_pi, m68k_op_addi_8_pi, m68k_op_addi_8_pi, m68k_op_addi_8_pi7, + m68k_op_addi_8_pd, m68k_op_addi_8_pd, m68k_op_addi_8_pd, m68k_op_addi_8_pd, m68k_op_addi_8_pd, m68k_op_addi_8_pd, m68k_op_addi_8_pd, m68k_op_addi_8_pd7, + m68k_op_addi_8_di, m68k_op_addi_8_di, m68k_op_addi_8_di, m68k_op_addi_8_di, m68k_op_addi_8_di, m68k_op_addi_8_di, m68k_op_addi_8_di, m68k_op_addi_8_di, + m68k_op_addi_8_ix, m68k_op_addi_8_ix, m68k_op_addi_8_ix, m68k_op_addi_8_ix, m68k_op_addi_8_ix, m68k_op_addi_8_ix, m68k_op_addi_8_ix, m68k_op_addi_8_ix, + m68k_op_addi_8_aw, m68k_op_addi_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addi_16_d, m68k_op_addi_16_d, m68k_op_addi_16_d, m68k_op_addi_16_d, m68k_op_addi_16_d, m68k_op_addi_16_d, m68k_op_addi_16_d, m68k_op_addi_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addi_16_ai, m68k_op_addi_16_ai, m68k_op_addi_16_ai, m68k_op_addi_16_ai, m68k_op_addi_16_ai, m68k_op_addi_16_ai, m68k_op_addi_16_ai, m68k_op_addi_16_ai, + m68k_op_addi_16_pi, m68k_op_addi_16_pi, m68k_op_addi_16_pi, m68k_op_addi_16_pi, m68k_op_addi_16_pi, m68k_op_addi_16_pi, m68k_op_addi_16_pi, m68k_op_addi_16_pi, + m68k_op_addi_16_pd, m68k_op_addi_16_pd, m68k_op_addi_16_pd, m68k_op_addi_16_pd, m68k_op_addi_16_pd, m68k_op_addi_16_pd, m68k_op_addi_16_pd, m68k_op_addi_16_pd, + m68k_op_addi_16_di, m68k_op_addi_16_di, m68k_op_addi_16_di, m68k_op_addi_16_di, m68k_op_addi_16_di, m68k_op_addi_16_di, m68k_op_addi_16_di, m68k_op_addi_16_di, + m68k_op_addi_16_ix, m68k_op_addi_16_ix, m68k_op_addi_16_ix, m68k_op_addi_16_ix, m68k_op_addi_16_ix, m68k_op_addi_16_ix, m68k_op_addi_16_ix, m68k_op_addi_16_ix, + m68k_op_addi_16_aw, m68k_op_addi_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addi_32_d, m68k_op_addi_32_d, m68k_op_addi_32_d, m68k_op_addi_32_d, m68k_op_addi_32_d, m68k_op_addi_32_d, m68k_op_addi_32_d, m68k_op_addi_32_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addi_32_ai, m68k_op_addi_32_ai, m68k_op_addi_32_ai, m68k_op_addi_32_ai, m68k_op_addi_32_ai, m68k_op_addi_32_ai, m68k_op_addi_32_ai, m68k_op_addi_32_ai, + m68k_op_addi_32_pi, m68k_op_addi_32_pi, m68k_op_addi_32_pi, m68k_op_addi_32_pi, m68k_op_addi_32_pi, m68k_op_addi_32_pi, m68k_op_addi_32_pi, m68k_op_addi_32_pi, + m68k_op_addi_32_pd, m68k_op_addi_32_pd, m68k_op_addi_32_pd, m68k_op_addi_32_pd, m68k_op_addi_32_pd, m68k_op_addi_32_pd, m68k_op_addi_32_pd, m68k_op_addi_32_pd, + m68k_op_addi_32_di, m68k_op_addi_32_di, m68k_op_addi_32_di, m68k_op_addi_32_di, m68k_op_addi_32_di, m68k_op_addi_32_di, m68k_op_addi_32_di, m68k_op_addi_32_di, + m68k_op_addi_32_ix, m68k_op_addi_32_ix, m68k_op_addi_32_ix, m68k_op_addi_32_ix, m68k_op_addi_32_ix, m68k_op_addi_32_ix, m68k_op_addi_32_ix, m68k_op_addi_32_ix, + m68k_op_addi_32_aw, m68k_op_addi_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, + m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, + m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, + m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi7, + m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd7, + m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, + m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, + m68k_op_btst_8_r_aw, m68k_op_btst_8_r_al, m68k_op_btst_8_r_pcdi, m68k_op_btst_8_r_pcix, m68k_op_btst_8_r_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, + m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, + m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, + m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi7, + m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd7, + m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, + m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, + m68k_op_bchg_8_r_aw, m68k_op_bchg_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, + m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, + m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, + m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi7, + m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd7, + m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, + m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, + m68k_op_bclr_8_r_aw, m68k_op_bclr_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, + m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, + m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, + m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi7, + m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd7, + m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, + m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, + m68k_op_bset_8_r_aw, m68k_op_bset_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_btst_32_s_d, m68k_op_btst_32_s_d, m68k_op_btst_32_s_d, m68k_op_btst_32_s_d, m68k_op_btst_32_s_d, m68k_op_btst_32_s_d, m68k_op_btst_32_s_d, m68k_op_btst_32_s_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_btst_8_s_ai, m68k_op_btst_8_s_ai, m68k_op_btst_8_s_ai, m68k_op_btst_8_s_ai, m68k_op_btst_8_s_ai, m68k_op_btst_8_s_ai, m68k_op_btst_8_s_ai, m68k_op_btst_8_s_ai, + m68k_op_btst_8_s_pi, m68k_op_btst_8_s_pi, m68k_op_btst_8_s_pi, m68k_op_btst_8_s_pi, m68k_op_btst_8_s_pi, m68k_op_btst_8_s_pi, m68k_op_btst_8_s_pi, m68k_op_btst_8_s_pi7, + m68k_op_btst_8_s_pd, m68k_op_btst_8_s_pd, m68k_op_btst_8_s_pd, m68k_op_btst_8_s_pd, m68k_op_btst_8_s_pd, m68k_op_btst_8_s_pd, m68k_op_btst_8_s_pd, m68k_op_btst_8_s_pd7, + m68k_op_btst_8_s_di, m68k_op_btst_8_s_di, m68k_op_btst_8_s_di, m68k_op_btst_8_s_di, m68k_op_btst_8_s_di, m68k_op_btst_8_s_di, m68k_op_btst_8_s_di, m68k_op_btst_8_s_di, + m68k_op_btst_8_s_ix, m68k_op_btst_8_s_ix, m68k_op_btst_8_s_ix, m68k_op_btst_8_s_ix, m68k_op_btst_8_s_ix, m68k_op_btst_8_s_ix, m68k_op_btst_8_s_ix, m68k_op_btst_8_s_ix, + m68k_op_btst_8_s_aw, m68k_op_btst_8_s_al, m68k_op_btst_8_s_pcdi, m68k_op_btst_8_s_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bchg_32_s_d, m68k_op_bchg_32_s_d, m68k_op_bchg_32_s_d, m68k_op_bchg_32_s_d, m68k_op_bchg_32_s_d, m68k_op_bchg_32_s_d, m68k_op_bchg_32_s_d, m68k_op_bchg_32_s_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bchg_8_s_ai, m68k_op_bchg_8_s_ai, m68k_op_bchg_8_s_ai, m68k_op_bchg_8_s_ai, m68k_op_bchg_8_s_ai, m68k_op_bchg_8_s_ai, m68k_op_bchg_8_s_ai, m68k_op_bchg_8_s_ai, + m68k_op_bchg_8_s_pi, m68k_op_bchg_8_s_pi, m68k_op_bchg_8_s_pi, m68k_op_bchg_8_s_pi, m68k_op_bchg_8_s_pi, m68k_op_bchg_8_s_pi, m68k_op_bchg_8_s_pi, m68k_op_bchg_8_s_pi7, + m68k_op_bchg_8_s_pd, m68k_op_bchg_8_s_pd, m68k_op_bchg_8_s_pd, m68k_op_bchg_8_s_pd, m68k_op_bchg_8_s_pd, m68k_op_bchg_8_s_pd, m68k_op_bchg_8_s_pd, m68k_op_bchg_8_s_pd7, + m68k_op_bchg_8_s_di, m68k_op_bchg_8_s_di, m68k_op_bchg_8_s_di, m68k_op_bchg_8_s_di, m68k_op_bchg_8_s_di, m68k_op_bchg_8_s_di, m68k_op_bchg_8_s_di, m68k_op_bchg_8_s_di, + m68k_op_bchg_8_s_ix, m68k_op_bchg_8_s_ix, m68k_op_bchg_8_s_ix, m68k_op_bchg_8_s_ix, m68k_op_bchg_8_s_ix, m68k_op_bchg_8_s_ix, m68k_op_bchg_8_s_ix, m68k_op_bchg_8_s_ix, + m68k_op_bchg_8_s_aw, m68k_op_bchg_8_s_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bclr_32_s_d, m68k_op_bclr_32_s_d, m68k_op_bclr_32_s_d, m68k_op_bclr_32_s_d, m68k_op_bclr_32_s_d, m68k_op_bclr_32_s_d, m68k_op_bclr_32_s_d, m68k_op_bclr_32_s_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bclr_8_s_ai, m68k_op_bclr_8_s_ai, m68k_op_bclr_8_s_ai, m68k_op_bclr_8_s_ai, m68k_op_bclr_8_s_ai, m68k_op_bclr_8_s_ai, m68k_op_bclr_8_s_ai, m68k_op_bclr_8_s_ai, + m68k_op_bclr_8_s_pi, m68k_op_bclr_8_s_pi, m68k_op_bclr_8_s_pi, m68k_op_bclr_8_s_pi, m68k_op_bclr_8_s_pi, m68k_op_bclr_8_s_pi, m68k_op_bclr_8_s_pi, m68k_op_bclr_8_s_pi7, + m68k_op_bclr_8_s_pd, m68k_op_bclr_8_s_pd, m68k_op_bclr_8_s_pd, m68k_op_bclr_8_s_pd, m68k_op_bclr_8_s_pd, m68k_op_bclr_8_s_pd, m68k_op_bclr_8_s_pd, m68k_op_bclr_8_s_pd7, + m68k_op_bclr_8_s_di, m68k_op_bclr_8_s_di, m68k_op_bclr_8_s_di, m68k_op_bclr_8_s_di, m68k_op_bclr_8_s_di, m68k_op_bclr_8_s_di, m68k_op_bclr_8_s_di, m68k_op_bclr_8_s_di, + m68k_op_bclr_8_s_ix, m68k_op_bclr_8_s_ix, m68k_op_bclr_8_s_ix, m68k_op_bclr_8_s_ix, m68k_op_bclr_8_s_ix, m68k_op_bclr_8_s_ix, m68k_op_bclr_8_s_ix, m68k_op_bclr_8_s_ix, + m68k_op_bclr_8_s_aw, m68k_op_bclr_8_s_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bset_32_s_d, m68k_op_bset_32_s_d, m68k_op_bset_32_s_d, m68k_op_bset_32_s_d, m68k_op_bset_32_s_d, m68k_op_bset_32_s_d, m68k_op_bset_32_s_d, m68k_op_bset_32_s_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bset_8_s_ai, m68k_op_bset_8_s_ai, m68k_op_bset_8_s_ai, m68k_op_bset_8_s_ai, m68k_op_bset_8_s_ai, m68k_op_bset_8_s_ai, m68k_op_bset_8_s_ai, m68k_op_bset_8_s_ai, + m68k_op_bset_8_s_pi, m68k_op_bset_8_s_pi, m68k_op_bset_8_s_pi, m68k_op_bset_8_s_pi, m68k_op_bset_8_s_pi, m68k_op_bset_8_s_pi, m68k_op_bset_8_s_pi, m68k_op_bset_8_s_pi7, + m68k_op_bset_8_s_pd, m68k_op_bset_8_s_pd, m68k_op_bset_8_s_pd, m68k_op_bset_8_s_pd, m68k_op_bset_8_s_pd, m68k_op_bset_8_s_pd, m68k_op_bset_8_s_pd, m68k_op_bset_8_s_pd7, + m68k_op_bset_8_s_di, m68k_op_bset_8_s_di, m68k_op_bset_8_s_di, m68k_op_bset_8_s_di, m68k_op_bset_8_s_di, m68k_op_bset_8_s_di, m68k_op_bset_8_s_di, m68k_op_bset_8_s_di, + m68k_op_bset_8_s_ix, m68k_op_bset_8_s_ix, m68k_op_bset_8_s_ix, m68k_op_bset_8_s_ix, m68k_op_bset_8_s_ix, m68k_op_bset_8_s_ix, m68k_op_bset_8_s_ix, m68k_op_bset_8_s_ix, + m68k_op_bset_8_s_aw, m68k_op_bset_8_s_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, + m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, + m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, + m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi7, + m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd7, + m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, + m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, + m68k_op_btst_8_r_aw, m68k_op_btst_8_r_al, m68k_op_btst_8_r_pcdi, m68k_op_btst_8_r_pcix, m68k_op_btst_8_r_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, + m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, + m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, + m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi7, + m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd7, + m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, + m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, + m68k_op_bchg_8_r_aw, m68k_op_bchg_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, + m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, + m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, + m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi7, + m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd7, + m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, + m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, + m68k_op_bclr_8_r_aw, m68k_op_bclr_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, + m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, + m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, + m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi7, + m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd7, + m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, + m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, + m68k_op_bset_8_r_aw, m68k_op_bset_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eori_8_d, m68k_op_eori_8_d, m68k_op_eori_8_d, m68k_op_eori_8_d, m68k_op_eori_8_d, m68k_op_eori_8_d, m68k_op_eori_8_d, m68k_op_eori_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eori_8_ai, m68k_op_eori_8_ai, m68k_op_eori_8_ai, m68k_op_eori_8_ai, m68k_op_eori_8_ai, m68k_op_eori_8_ai, m68k_op_eori_8_ai, m68k_op_eori_8_ai, + m68k_op_eori_8_pi, m68k_op_eori_8_pi, m68k_op_eori_8_pi, m68k_op_eori_8_pi, m68k_op_eori_8_pi, m68k_op_eori_8_pi, m68k_op_eori_8_pi, m68k_op_eori_8_pi7, + m68k_op_eori_8_pd, m68k_op_eori_8_pd, m68k_op_eori_8_pd, m68k_op_eori_8_pd, m68k_op_eori_8_pd, m68k_op_eori_8_pd, m68k_op_eori_8_pd, m68k_op_eori_8_pd7, + m68k_op_eori_8_di, m68k_op_eori_8_di, m68k_op_eori_8_di, m68k_op_eori_8_di, m68k_op_eori_8_di, m68k_op_eori_8_di, m68k_op_eori_8_di, m68k_op_eori_8_di, + m68k_op_eori_8_ix, m68k_op_eori_8_ix, m68k_op_eori_8_ix, m68k_op_eori_8_ix, m68k_op_eori_8_ix, m68k_op_eori_8_ix, m68k_op_eori_8_ix, m68k_op_eori_8_ix, + m68k_op_eori_8_aw, m68k_op_eori_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_eori_16_toc, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eori_16_d, m68k_op_eori_16_d, m68k_op_eori_16_d, m68k_op_eori_16_d, m68k_op_eori_16_d, m68k_op_eori_16_d, m68k_op_eori_16_d, m68k_op_eori_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eori_16_ai, m68k_op_eori_16_ai, m68k_op_eori_16_ai, m68k_op_eori_16_ai, m68k_op_eori_16_ai, m68k_op_eori_16_ai, m68k_op_eori_16_ai, m68k_op_eori_16_ai, + m68k_op_eori_16_pi, m68k_op_eori_16_pi, m68k_op_eori_16_pi, m68k_op_eori_16_pi, m68k_op_eori_16_pi, m68k_op_eori_16_pi, m68k_op_eori_16_pi, m68k_op_eori_16_pi, + m68k_op_eori_16_pd, m68k_op_eori_16_pd, m68k_op_eori_16_pd, m68k_op_eori_16_pd, m68k_op_eori_16_pd, m68k_op_eori_16_pd, m68k_op_eori_16_pd, m68k_op_eori_16_pd, + m68k_op_eori_16_di, m68k_op_eori_16_di, m68k_op_eori_16_di, m68k_op_eori_16_di, m68k_op_eori_16_di, m68k_op_eori_16_di, m68k_op_eori_16_di, m68k_op_eori_16_di, + m68k_op_eori_16_ix, m68k_op_eori_16_ix, m68k_op_eori_16_ix, m68k_op_eori_16_ix, m68k_op_eori_16_ix, m68k_op_eori_16_ix, m68k_op_eori_16_ix, m68k_op_eori_16_ix, + m68k_op_eori_16_aw, m68k_op_eori_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_eori_16_tos, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eori_32_d, m68k_op_eori_32_d, m68k_op_eori_32_d, m68k_op_eori_32_d, m68k_op_eori_32_d, m68k_op_eori_32_d, m68k_op_eori_32_d, m68k_op_eori_32_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eori_32_ai, m68k_op_eori_32_ai, m68k_op_eori_32_ai, m68k_op_eori_32_ai, m68k_op_eori_32_ai, m68k_op_eori_32_ai, m68k_op_eori_32_ai, m68k_op_eori_32_ai, + m68k_op_eori_32_pi, m68k_op_eori_32_pi, m68k_op_eori_32_pi, m68k_op_eori_32_pi, m68k_op_eori_32_pi, m68k_op_eori_32_pi, m68k_op_eori_32_pi, m68k_op_eori_32_pi, + m68k_op_eori_32_pd, m68k_op_eori_32_pd, m68k_op_eori_32_pd, m68k_op_eori_32_pd, m68k_op_eori_32_pd, m68k_op_eori_32_pd, m68k_op_eori_32_pd, m68k_op_eori_32_pd, + m68k_op_eori_32_di, m68k_op_eori_32_di, m68k_op_eori_32_di, m68k_op_eori_32_di, m68k_op_eori_32_di, m68k_op_eori_32_di, m68k_op_eori_32_di, m68k_op_eori_32_di, + m68k_op_eori_32_ix, m68k_op_eori_32_ix, m68k_op_eori_32_ix, m68k_op_eori_32_ix, m68k_op_eori_32_ix, m68k_op_eori_32_ix, m68k_op_eori_32_ix, m68k_op_eori_32_ix, + m68k_op_eori_32_aw, m68k_op_eori_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, + m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, + m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, + m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi7, + m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd7, + m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, + m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, + m68k_op_btst_8_r_aw, m68k_op_btst_8_r_al, m68k_op_btst_8_r_pcdi, m68k_op_btst_8_r_pcix, m68k_op_btst_8_r_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, + m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, + m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, + m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi7, + m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd7, + m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, + m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, + m68k_op_bchg_8_r_aw, m68k_op_bchg_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, + m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, + m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, + m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi7, + m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd7, + m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, + m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, + m68k_op_bclr_8_r_aw, m68k_op_bclr_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, + m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, + m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, + m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi7, + m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd7, + m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, + m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, + m68k_op_bset_8_r_aw, m68k_op_bset_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpi_8_d, m68k_op_cmpi_8_d, m68k_op_cmpi_8_d, m68k_op_cmpi_8_d, m68k_op_cmpi_8_d, m68k_op_cmpi_8_d, m68k_op_cmpi_8_d, m68k_op_cmpi_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpi_8_ai, m68k_op_cmpi_8_ai, m68k_op_cmpi_8_ai, m68k_op_cmpi_8_ai, m68k_op_cmpi_8_ai, m68k_op_cmpi_8_ai, m68k_op_cmpi_8_ai, m68k_op_cmpi_8_ai, + m68k_op_cmpi_8_pi, m68k_op_cmpi_8_pi, m68k_op_cmpi_8_pi, m68k_op_cmpi_8_pi, m68k_op_cmpi_8_pi, m68k_op_cmpi_8_pi, m68k_op_cmpi_8_pi, m68k_op_cmpi_8_pi7, + m68k_op_cmpi_8_pd, m68k_op_cmpi_8_pd, m68k_op_cmpi_8_pd, m68k_op_cmpi_8_pd, m68k_op_cmpi_8_pd, m68k_op_cmpi_8_pd, m68k_op_cmpi_8_pd, m68k_op_cmpi_8_pd7, + m68k_op_cmpi_8_di, m68k_op_cmpi_8_di, m68k_op_cmpi_8_di, m68k_op_cmpi_8_di, m68k_op_cmpi_8_di, m68k_op_cmpi_8_di, m68k_op_cmpi_8_di, m68k_op_cmpi_8_di, + m68k_op_cmpi_8_ix, m68k_op_cmpi_8_ix, m68k_op_cmpi_8_ix, m68k_op_cmpi_8_ix, m68k_op_cmpi_8_ix, m68k_op_cmpi_8_ix, m68k_op_cmpi_8_ix, m68k_op_cmpi_8_ix, + m68k_op_cmpi_8_aw, m68k_op_cmpi_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpi_16_d, m68k_op_cmpi_16_d, m68k_op_cmpi_16_d, m68k_op_cmpi_16_d, m68k_op_cmpi_16_d, m68k_op_cmpi_16_d, m68k_op_cmpi_16_d, m68k_op_cmpi_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpi_16_ai, m68k_op_cmpi_16_ai, m68k_op_cmpi_16_ai, m68k_op_cmpi_16_ai, m68k_op_cmpi_16_ai, m68k_op_cmpi_16_ai, m68k_op_cmpi_16_ai, m68k_op_cmpi_16_ai, + m68k_op_cmpi_16_pi, m68k_op_cmpi_16_pi, m68k_op_cmpi_16_pi, m68k_op_cmpi_16_pi, m68k_op_cmpi_16_pi, m68k_op_cmpi_16_pi, m68k_op_cmpi_16_pi, m68k_op_cmpi_16_pi, + m68k_op_cmpi_16_pd, m68k_op_cmpi_16_pd, m68k_op_cmpi_16_pd, m68k_op_cmpi_16_pd, m68k_op_cmpi_16_pd, m68k_op_cmpi_16_pd, m68k_op_cmpi_16_pd, m68k_op_cmpi_16_pd, + m68k_op_cmpi_16_di, m68k_op_cmpi_16_di, m68k_op_cmpi_16_di, m68k_op_cmpi_16_di, m68k_op_cmpi_16_di, m68k_op_cmpi_16_di, m68k_op_cmpi_16_di, m68k_op_cmpi_16_di, + m68k_op_cmpi_16_ix, m68k_op_cmpi_16_ix, m68k_op_cmpi_16_ix, m68k_op_cmpi_16_ix, m68k_op_cmpi_16_ix, m68k_op_cmpi_16_ix, m68k_op_cmpi_16_ix, m68k_op_cmpi_16_ix, + m68k_op_cmpi_16_aw, m68k_op_cmpi_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpi_32_d, m68k_op_cmpi_32_d, m68k_op_cmpi_32_d, m68k_op_cmpi_32_d, m68k_op_cmpi_32_d, m68k_op_cmpi_32_d, m68k_op_cmpi_32_d, m68k_op_cmpi_32_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpi_32_ai, m68k_op_cmpi_32_ai, m68k_op_cmpi_32_ai, m68k_op_cmpi_32_ai, m68k_op_cmpi_32_ai, m68k_op_cmpi_32_ai, m68k_op_cmpi_32_ai, m68k_op_cmpi_32_ai, + m68k_op_cmpi_32_pi, m68k_op_cmpi_32_pi, m68k_op_cmpi_32_pi, m68k_op_cmpi_32_pi, m68k_op_cmpi_32_pi, m68k_op_cmpi_32_pi, m68k_op_cmpi_32_pi, m68k_op_cmpi_32_pi, + m68k_op_cmpi_32_pd, m68k_op_cmpi_32_pd, m68k_op_cmpi_32_pd, m68k_op_cmpi_32_pd, m68k_op_cmpi_32_pd, m68k_op_cmpi_32_pd, m68k_op_cmpi_32_pd, m68k_op_cmpi_32_pd, + m68k_op_cmpi_32_di, m68k_op_cmpi_32_di, m68k_op_cmpi_32_di, m68k_op_cmpi_32_di, m68k_op_cmpi_32_di, m68k_op_cmpi_32_di, m68k_op_cmpi_32_di, m68k_op_cmpi_32_di, + m68k_op_cmpi_32_ix, m68k_op_cmpi_32_ix, m68k_op_cmpi_32_ix, m68k_op_cmpi_32_ix, m68k_op_cmpi_32_ix, m68k_op_cmpi_32_ix, m68k_op_cmpi_32_ix, m68k_op_cmpi_32_ix, + m68k_op_cmpi_32_aw, m68k_op_cmpi_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, + m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, + m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, + m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi7, + m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd7, + m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, + m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, + m68k_op_btst_8_r_aw, m68k_op_btst_8_r_al, m68k_op_btst_8_r_pcdi, m68k_op_btst_8_r_pcix, m68k_op_btst_8_r_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, + m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, + m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, + m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi7, + m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd7, + m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, + m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, + m68k_op_bchg_8_r_aw, m68k_op_bchg_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, + m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, + m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, + m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi7, + m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd7, + m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, + m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, + m68k_op_bclr_8_r_aw, m68k_op_bclr_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, + m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, + m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, + m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi7, + m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd7, + m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, + m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, + m68k_op_bset_8_r_aw, m68k_op_bset_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, m68k_op_btst_32_r_d, + m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, m68k_op_movep_16_er, + m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, m68k_op_btst_8_r_ai, + m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi, m68k_op_btst_8_r_pi7, + m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd, m68k_op_btst_8_r_pd7, + m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, m68k_op_btst_8_r_di, + m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, m68k_op_btst_8_r_ix, + m68k_op_btst_8_r_aw, m68k_op_btst_8_r_al, m68k_op_btst_8_r_pcdi, m68k_op_btst_8_r_pcix, m68k_op_btst_8_r_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, m68k_op_bchg_32_r_d, + m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, m68k_op_movep_32_er, + m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, m68k_op_bchg_8_r_ai, + m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi, m68k_op_bchg_8_r_pi7, + m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd, m68k_op_bchg_8_r_pd7, + m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, m68k_op_bchg_8_r_di, + m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, m68k_op_bchg_8_r_ix, + m68k_op_bchg_8_r_aw, m68k_op_bchg_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, m68k_op_bclr_32_r_d, + m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, m68k_op_movep_16_re, + m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, m68k_op_bclr_8_r_ai, + m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi, m68k_op_bclr_8_r_pi7, + m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd, m68k_op_bclr_8_r_pd7, + m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, m68k_op_bclr_8_r_di, + m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, m68k_op_bclr_8_r_ix, + m68k_op_bclr_8_r_aw, m68k_op_bclr_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, m68k_op_bset_32_r_d, + m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, m68k_op_movep_32_re, + m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, m68k_op_bset_8_r_ai, + m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi, m68k_op_bset_8_r_pi7, + m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd, m68k_op_bset_8_r_pd7, + m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, m68k_op_bset_8_r_di, + m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, m68k_op_bset_8_r_ix, + m68k_op_bset_8_r_aw, m68k_op_bset_8_r_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, + m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi7, + m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd7, + m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, + m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, + m68k_op_move_8_d_aw, m68k_op_move_8_d_al, m68k_op_move_8_d_pcdi, m68k_op_move_8_d_pcix, m68k_op_move_8_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, + m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi7, + m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd7, + m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, + m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, + m68k_op_move_8_ai_aw, m68k_op_move_8_ai_al, m68k_op_move_8_ai_pcdi, m68k_op_move_8_ai_pcix, m68k_op_move_8_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, + m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi7, + m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd7, + m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, + m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, + m68k_op_move_8_pi_aw, m68k_op_move_8_pi_al, m68k_op_move_8_pi_pcdi, m68k_op_move_8_pi_pcix, m68k_op_move_8_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, + m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi7, + m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd7, + m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, + m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, + m68k_op_move_8_pd_aw, m68k_op_move_8_pd_al, m68k_op_move_8_pd_pcdi, m68k_op_move_8_pd_pcix, m68k_op_move_8_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, + m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi7, + m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd7, + m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, + m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, + m68k_op_move_8_di_aw, m68k_op_move_8_di_al, m68k_op_move_8_di_pcdi, m68k_op_move_8_di_pcix, m68k_op_move_8_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, + m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi7, + m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd7, + m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, + m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, + m68k_op_move_8_ix_aw, m68k_op_move_8_ix_al, m68k_op_move_8_ix_pcdi, m68k_op_move_8_ix_pcix, m68k_op_move_8_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_aw_d, m68k_op_move_8_aw_d, m68k_op_move_8_aw_d, m68k_op_move_8_aw_d, m68k_op_move_8_aw_d, m68k_op_move_8_aw_d, m68k_op_move_8_aw_d, m68k_op_move_8_aw_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_aw_ai, m68k_op_move_8_aw_ai, m68k_op_move_8_aw_ai, m68k_op_move_8_aw_ai, m68k_op_move_8_aw_ai, m68k_op_move_8_aw_ai, m68k_op_move_8_aw_ai, m68k_op_move_8_aw_ai, + m68k_op_move_8_aw_pi, m68k_op_move_8_aw_pi, m68k_op_move_8_aw_pi, m68k_op_move_8_aw_pi, m68k_op_move_8_aw_pi, m68k_op_move_8_aw_pi, m68k_op_move_8_aw_pi, m68k_op_move_8_aw_pi7, + m68k_op_move_8_aw_pd, m68k_op_move_8_aw_pd, m68k_op_move_8_aw_pd, m68k_op_move_8_aw_pd, m68k_op_move_8_aw_pd, m68k_op_move_8_aw_pd, m68k_op_move_8_aw_pd, m68k_op_move_8_aw_pd7, + m68k_op_move_8_aw_di, m68k_op_move_8_aw_di, m68k_op_move_8_aw_di, m68k_op_move_8_aw_di, m68k_op_move_8_aw_di, m68k_op_move_8_aw_di, m68k_op_move_8_aw_di, m68k_op_move_8_aw_di, + m68k_op_move_8_aw_ix, m68k_op_move_8_aw_ix, m68k_op_move_8_aw_ix, m68k_op_move_8_aw_ix, m68k_op_move_8_aw_ix, m68k_op_move_8_aw_ix, m68k_op_move_8_aw_ix, m68k_op_move_8_aw_ix, + m68k_op_move_8_aw_aw, m68k_op_move_8_aw_al, m68k_op_move_8_aw_pcdi, m68k_op_move_8_aw_pcix, m68k_op_move_8_aw_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, + m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi7, + m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd7, + m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, + m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, + m68k_op_move_8_d_aw, m68k_op_move_8_d_al, m68k_op_move_8_d_pcdi, m68k_op_move_8_d_pcix, m68k_op_move_8_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, + m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi7, + m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd7, + m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, + m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, + m68k_op_move_8_ai_aw, m68k_op_move_8_ai_al, m68k_op_move_8_ai_pcdi, m68k_op_move_8_ai_pcix, m68k_op_move_8_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, + m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi7, + m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd7, + m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, + m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, + m68k_op_move_8_pi_aw, m68k_op_move_8_pi_al, m68k_op_move_8_pi_pcdi, m68k_op_move_8_pi_pcix, m68k_op_move_8_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, + m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi7, + m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd7, + m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, + m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, + m68k_op_move_8_pd_aw, m68k_op_move_8_pd_al, m68k_op_move_8_pd_pcdi, m68k_op_move_8_pd_pcix, m68k_op_move_8_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, + m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi7, + m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd7, + m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, + m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, + m68k_op_move_8_di_aw, m68k_op_move_8_di_al, m68k_op_move_8_di_pcdi, m68k_op_move_8_di_pcix, m68k_op_move_8_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, + m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi7, + m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd7, + m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, + m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, + m68k_op_move_8_ix_aw, m68k_op_move_8_ix_al, m68k_op_move_8_ix_pcdi, m68k_op_move_8_ix_pcix, m68k_op_move_8_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_al_d, m68k_op_move_8_al_d, m68k_op_move_8_al_d, m68k_op_move_8_al_d, m68k_op_move_8_al_d, m68k_op_move_8_al_d, m68k_op_move_8_al_d, m68k_op_move_8_al_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_al_ai, m68k_op_move_8_al_ai, m68k_op_move_8_al_ai, m68k_op_move_8_al_ai, m68k_op_move_8_al_ai, m68k_op_move_8_al_ai, m68k_op_move_8_al_ai, m68k_op_move_8_al_ai, + m68k_op_move_8_al_pi, m68k_op_move_8_al_pi, m68k_op_move_8_al_pi, m68k_op_move_8_al_pi, m68k_op_move_8_al_pi, m68k_op_move_8_al_pi, m68k_op_move_8_al_pi, m68k_op_move_8_al_pi7, + m68k_op_move_8_al_pd, m68k_op_move_8_al_pd, m68k_op_move_8_al_pd, m68k_op_move_8_al_pd, m68k_op_move_8_al_pd, m68k_op_move_8_al_pd, m68k_op_move_8_al_pd, m68k_op_move_8_al_pd7, + m68k_op_move_8_al_di, m68k_op_move_8_al_di, m68k_op_move_8_al_di, m68k_op_move_8_al_di, m68k_op_move_8_al_di, m68k_op_move_8_al_di, m68k_op_move_8_al_di, m68k_op_move_8_al_di, + m68k_op_move_8_al_ix, m68k_op_move_8_al_ix, m68k_op_move_8_al_ix, m68k_op_move_8_al_ix, m68k_op_move_8_al_ix, m68k_op_move_8_al_ix, m68k_op_move_8_al_ix, m68k_op_move_8_al_ix, + m68k_op_move_8_al_aw, m68k_op_move_8_al_al, m68k_op_move_8_al_pcdi, m68k_op_move_8_al_pcix, m68k_op_move_8_al_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, + m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi7, + m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd7, + m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, + m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, + m68k_op_move_8_d_aw, m68k_op_move_8_d_al, m68k_op_move_8_d_pcdi, m68k_op_move_8_d_pcix, m68k_op_move_8_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, + m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi7, + m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd7, + m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, + m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, + m68k_op_move_8_ai_aw, m68k_op_move_8_ai_al, m68k_op_move_8_ai_pcdi, m68k_op_move_8_ai_pcix, m68k_op_move_8_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, + m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi7, + m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd7, + m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, + m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, + m68k_op_move_8_pi_aw, m68k_op_move_8_pi_al, m68k_op_move_8_pi_pcdi, m68k_op_move_8_pi_pcix, m68k_op_move_8_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, + m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi7, + m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd7, + m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, + m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, + m68k_op_move_8_pd_aw, m68k_op_move_8_pd_al, m68k_op_move_8_pd_pcdi, m68k_op_move_8_pd_pcix, m68k_op_move_8_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, + m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi7, + m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd7, + m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, + m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, + m68k_op_move_8_di_aw, m68k_op_move_8_di_al, m68k_op_move_8_di_pcdi, m68k_op_move_8_di_pcix, m68k_op_move_8_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, + m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi7, + m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd7, + m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, + m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, + m68k_op_move_8_ix_aw, m68k_op_move_8_ix_al, m68k_op_move_8_ix_pcdi, m68k_op_move_8_ix_pcix, m68k_op_move_8_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, + m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi7, + m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd7, + m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, + m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, + m68k_op_move_8_d_aw, m68k_op_move_8_d_al, m68k_op_move_8_d_pcdi, m68k_op_move_8_d_pcix, m68k_op_move_8_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, + m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi7, + m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd7, + m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, + m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, + m68k_op_move_8_ai_aw, m68k_op_move_8_ai_al, m68k_op_move_8_ai_pcdi, m68k_op_move_8_ai_pcix, m68k_op_move_8_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, + m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi7, + m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd7, + m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, + m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, + m68k_op_move_8_pi_aw, m68k_op_move_8_pi_al, m68k_op_move_8_pi_pcdi, m68k_op_move_8_pi_pcix, m68k_op_move_8_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, + m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi7, + m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd7, + m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, + m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, + m68k_op_move_8_pd_aw, m68k_op_move_8_pd_al, m68k_op_move_8_pd_pcdi, m68k_op_move_8_pd_pcix, m68k_op_move_8_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, + m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi7, + m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd7, + m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, + m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, + m68k_op_move_8_di_aw, m68k_op_move_8_di_al, m68k_op_move_8_di_pcdi, m68k_op_move_8_di_pcix, m68k_op_move_8_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, + m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi7, + m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd7, + m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, + m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, + m68k_op_move_8_ix_aw, m68k_op_move_8_ix_al, m68k_op_move_8_ix_pcdi, m68k_op_move_8_ix_pcix, m68k_op_move_8_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, + m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi7, + m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd7, + m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, + m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, + m68k_op_move_8_d_aw, m68k_op_move_8_d_al, m68k_op_move_8_d_pcdi, m68k_op_move_8_d_pcix, m68k_op_move_8_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, + m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi7, + m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd7, + m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, + m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, + m68k_op_move_8_ai_aw, m68k_op_move_8_ai_al, m68k_op_move_8_ai_pcdi, m68k_op_move_8_ai_pcix, m68k_op_move_8_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, + m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi7, + m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd7, + m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, + m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, + m68k_op_move_8_pi_aw, m68k_op_move_8_pi_al, m68k_op_move_8_pi_pcdi, m68k_op_move_8_pi_pcix, m68k_op_move_8_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, + m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi7, + m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd7, + m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, + m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, + m68k_op_move_8_pd_aw, m68k_op_move_8_pd_al, m68k_op_move_8_pd_pcdi, m68k_op_move_8_pd_pcix, m68k_op_move_8_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, + m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi7, + m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd7, + m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, + m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, + m68k_op_move_8_di_aw, m68k_op_move_8_di_al, m68k_op_move_8_di_pcdi, m68k_op_move_8_di_pcix, m68k_op_move_8_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, + m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi7, + m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd7, + m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, + m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, + m68k_op_move_8_ix_aw, m68k_op_move_8_ix_al, m68k_op_move_8_ix_pcdi, m68k_op_move_8_ix_pcix, m68k_op_move_8_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, + m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi7, + m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd7, + m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, + m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, + m68k_op_move_8_d_aw, m68k_op_move_8_d_al, m68k_op_move_8_d_pcdi, m68k_op_move_8_d_pcix, m68k_op_move_8_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, + m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi7, + m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd7, + m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, + m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, + m68k_op_move_8_ai_aw, m68k_op_move_8_ai_al, m68k_op_move_8_ai_pcdi, m68k_op_move_8_ai_pcix, m68k_op_move_8_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, + m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi7, + m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd7, + m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, + m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, + m68k_op_move_8_pi_aw, m68k_op_move_8_pi_al, m68k_op_move_8_pi_pcdi, m68k_op_move_8_pi_pcix, m68k_op_move_8_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, + m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi7, + m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd7, + m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, + m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, + m68k_op_move_8_pd_aw, m68k_op_move_8_pd_al, m68k_op_move_8_pd_pcdi, m68k_op_move_8_pd_pcix, m68k_op_move_8_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, + m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi7, + m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd7, + m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, + m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, + m68k_op_move_8_di_aw, m68k_op_move_8_di_al, m68k_op_move_8_di_pcdi, m68k_op_move_8_di_pcix, m68k_op_move_8_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, + m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi7, + m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd7, + m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, + m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, + m68k_op_move_8_ix_aw, m68k_op_move_8_ix_al, m68k_op_move_8_ix_pcdi, m68k_op_move_8_ix_pcix, m68k_op_move_8_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, + m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi7, + m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd7, + m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, + m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, + m68k_op_move_8_d_aw, m68k_op_move_8_d_al, m68k_op_move_8_d_pcdi, m68k_op_move_8_d_pcix, m68k_op_move_8_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, + m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi7, + m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd7, + m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, + m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, + m68k_op_move_8_ai_aw, m68k_op_move_8_ai_al, m68k_op_move_8_ai_pcdi, m68k_op_move_8_ai_pcix, m68k_op_move_8_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, m68k_op_move_8_pi_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, m68k_op_move_8_pi_ai, + m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi, m68k_op_move_8_pi_pi7, + m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd, m68k_op_move_8_pi_pd7, + m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, m68k_op_move_8_pi_di, + m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, m68k_op_move_8_pi_ix, + m68k_op_move_8_pi_aw, m68k_op_move_8_pi_al, m68k_op_move_8_pi_pcdi, m68k_op_move_8_pi_pcix, m68k_op_move_8_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, m68k_op_move_8_pd_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, m68k_op_move_8_pd_ai, + m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi, m68k_op_move_8_pd_pi7, + m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd, m68k_op_move_8_pd_pd7, + m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, m68k_op_move_8_pd_di, + m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, m68k_op_move_8_pd_ix, + m68k_op_move_8_pd_aw, m68k_op_move_8_pd_al, m68k_op_move_8_pd_pcdi, m68k_op_move_8_pd_pcix, m68k_op_move_8_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, + m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi7, + m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd7, + m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, + m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, + m68k_op_move_8_di_aw, m68k_op_move_8_di_al, m68k_op_move_8_di_pcdi, m68k_op_move_8_di_pcix, m68k_op_move_8_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, + m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi7, + m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd7, + m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, + m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, + m68k_op_move_8_ix_aw, m68k_op_move_8_ix_al, m68k_op_move_8_ix_pcdi, m68k_op_move_8_ix_pcix, m68k_op_move_8_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, m68k_op_move_8_d_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, m68k_op_move_8_d_ai, + m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi, m68k_op_move_8_d_pi7, + m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd, m68k_op_move_8_d_pd7, + m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, m68k_op_move_8_d_di, + m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, m68k_op_move_8_d_ix, + m68k_op_move_8_d_aw, m68k_op_move_8_d_al, m68k_op_move_8_d_pcdi, m68k_op_move_8_d_pcix, m68k_op_move_8_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, m68k_op_move_8_ai_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, m68k_op_move_8_ai_ai, + m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi, m68k_op_move_8_ai_pi7, + m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd, m68k_op_move_8_ai_pd7, + m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, m68k_op_move_8_ai_di, + m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, m68k_op_move_8_ai_ix, + m68k_op_move_8_ai_aw, m68k_op_move_8_ai_al, m68k_op_move_8_ai_pcdi, m68k_op_move_8_ai_pcix, m68k_op_move_8_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi7_d, m68k_op_move_8_pi7_d, m68k_op_move_8_pi7_d, m68k_op_move_8_pi7_d, m68k_op_move_8_pi7_d, m68k_op_move_8_pi7_d, m68k_op_move_8_pi7_d, m68k_op_move_8_pi7_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pi7_ai, m68k_op_move_8_pi7_ai, m68k_op_move_8_pi7_ai, m68k_op_move_8_pi7_ai, m68k_op_move_8_pi7_ai, m68k_op_move_8_pi7_ai, m68k_op_move_8_pi7_ai, m68k_op_move_8_pi7_ai, + m68k_op_move_8_pi7_pi, m68k_op_move_8_pi7_pi, m68k_op_move_8_pi7_pi, m68k_op_move_8_pi7_pi, m68k_op_move_8_pi7_pi, m68k_op_move_8_pi7_pi, m68k_op_move_8_pi7_pi, m68k_op_move_8_pi7_pi7, + m68k_op_move_8_pi7_pd, m68k_op_move_8_pi7_pd, m68k_op_move_8_pi7_pd, m68k_op_move_8_pi7_pd, m68k_op_move_8_pi7_pd, m68k_op_move_8_pi7_pd, m68k_op_move_8_pi7_pd, m68k_op_move_8_pi7_pd7, + m68k_op_move_8_pi7_di, m68k_op_move_8_pi7_di, m68k_op_move_8_pi7_di, m68k_op_move_8_pi7_di, m68k_op_move_8_pi7_di, m68k_op_move_8_pi7_di, m68k_op_move_8_pi7_di, m68k_op_move_8_pi7_di, + m68k_op_move_8_pi7_ix, m68k_op_move_8_pi7_ix, m68k_op_move_8_pi7_ix, m68k_op_move_8_pi7_ix, m68k_op_move_8_pi7_ix, m68k_op_move_8_pi7_ix, m68k_op_move_8_pi7_ix, m68k_op_move_8_pi7_ix, + m68k_op_move_8_pi7_aw, m68k_op_move_8_pi7_al, m68k_op_move_8_pi7_pcdi, m68k_op_move_8_pi7_pcix, m68k_op_move_8_pi7_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd7_d, m68k_op_move_8_pd7_d, m68k_op_move_8_pd7_d, m68k_op_move_8_pd7_d, m68k_op_move_8_pd7_d, m68k_op_move_8_pd7_d, m68k_op_move_8_pd7_d, m68k_op_move_8_pd7_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_pd7_ai, m68k_op_move_8_pd7_ai, m68k_op_move_8_pd7_ai, m68k_op_move_8_pd7_ai, m68k_op_move_8_pd7_ai, m68k_op_move_8_pd7_ai, m68k_op_move_8_pd7_ai, m68k_op_move_8_pd7_ai, + m68k_op_move_8_pd7_pi, m68k_op_move_8_pd7_pi, m68k_op_move_8_pd7_pi, m68k_op_move_8_pd7_pi, m68k_op_move_8_pd7_pi, m68k_op_move_8_pd7_pi, m68k_op_move_8_pd7_pi, m68k_op_move_8_pd7_pi7, + m68k_op_move_8_pd7_pd, m68k_op_move_8_pd7_pd, m68k_op_move_8_pd7_pd, m68k_op_move_8_pd7_pd, m68k_op_move_8_pd7_pd, m68k_op_move_8_pd7_pd, m68k_op_move_8_pd7_pd, m68k_op_move_8_pd7_pd7, + m68k_op_move_8_pd7_di, m68k_op_move_8_pd7_di, m68k_op_move_8_pd7_di, m68k_op_move_8_pd7_di, m68k_op_move_8_pd7_di, m68k_op_move_8_pd7_di, m68k_op_move_8_pd7_di, m68k_op_move_8_pd7_di, + m68k_op_move_8_pd7_ix, m68k_op_move_8_pd7_ix, m68k_op_move_8_pd7_ix, m68k_op_move_8_pd7_ix, m68k_op_move_8_pd7_ix, m68k_op_move_8_pd7_ix, m68k_op_move_8_pd7_ix, m68k_op_move_8_pd7_ix, + m68k_op_move_8_pd7_aw, m68k_op_move_8_pd7_al, m68k_op_move_8_pd7_pcdi, m68k_op_move_8_pd7_pcix, m68k_op_move_8_pd7_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, m68k_op_move_8_di_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, m68k_op_move_8_di_ai, + m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi, m68k_op_move_8_di_pi7, + m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd, m68k_op_move_8_di_pd7, + m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, m68k_op_move_8_di_di, + m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, m68k_op_move_8_di_ix, + m68k_op_move_8_di_aw, m68k_op_move_8_di_al, m68k_op_move_8_di_pcdi, m68k_op_move_8_di_pcix, m68k_op_move_8_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, m68k_op_move_8_ix_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, m68k_op_move_8_ix_ai, + m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi, m68k_op_move_8_ix_pi7, + m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd, m68k_op_move_8_ix_pd7, + m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, m68k_op_move_8_ix_di, + m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, m68k_op_move_8_ix_ix, + m68k_op_move_8_ix_aw, m68k_op_move_8_ix_al, m68k_op_move_8_ix_pcdi, m68k_op_move_8_ix_pcix, m68k_op_move_8_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, + m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, + m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, + m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, + m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, + m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, + m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, + m68k_op_move_32_d_aw, m68k_op_move_32_d_al, m68k_op_move_32_d_pcdi, m68k_op_move_32_d_pcix, m68k_op_move_32_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, + m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, + m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, + m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, + m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, + m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, + m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, + m68k_op_movea_32_aw, m68k_op_movea_32_al, m68k_op_movea_32_pcdi, m68k_op_movea_32_pcix, m68k_op_movea_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, + m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, + m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, + m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, + m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, + m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, + m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, + m68k_op_move_32_ai_aw, m68k_op_move_32_ai_al, m68k_op_move_32_ai_pcdi, m68k_op_move_32_ai_pcix, m68k_op_move_32_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, + m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, + m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, + m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, + m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, + m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, + m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, + m68k_op_move_32_pi_aw, m68k_op_move_32_pi_al, m68k_op_move_32_pi_pcdi, m68k_op_move_32_pi_pcix, m68k_op_move_32_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, + m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, + m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, + m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, + m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, + m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, + m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, + m68k_op_move_32_pd_aw, m68k_op_move_32_pd_al, m68k_op_move_32_pd_pcdi, m68k_op_move_32_pd_pcix, m68k_op_move_32_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, + m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, + m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, + m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, + m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, + m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, + m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, + m68k_op_move_32_di_aw, m68k_op_move_32_di_al, m68k_op_move_32_di_pcdi, m68k_op_move_32_di_pcix, m68k_op_move_32_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, + m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, + m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, + m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, + m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, + m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, + m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, + m68k_op_move_32_ix_aw, m68k_op_move_32_ix_al, m68k_op_move_32_ix_pcdi, m68k_op_move_32_ix_pcix, m68k_op_move_32_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_aw_d, m68k_op_move_32_aw_d, m68k_op_move_32_aw_d, m68k_op_move_32_aw_d, m68k_op_move_32_aw_d, m68k_op_move_32_aw_d, m68k_op_move_32_aw_d, m68k_op_move_32_aw_d, + m68k_op_move_32_aw_a, m68k_op_move_32_aw_a, m68k_op_move_32_aw_a, m68k_op_move_32_aw_a, m68k_op_move_32_aw_a, m68k_op_move_32_aw_a, m68k_op_move_32_aw_a, m68k_op_move_32_aw_a, + m68k_op_move_32_aw_ai, m68k_op_move_32_aw_ai, m68k_op_move_32_aw_ai, m68k_op_move_32_aw_ai, m68k_op_move_32_aw_ai, m68k_op_move_32_aw_ai, m68k_op_move_32_aw_ai, m68k_op_move_32_aw_ai, + m68k_op_move_32_aw_pi, m68k_op_move_32_aw_pi, m68k_op_move_32_aw_pi, m68k_op_move_32_aw_pi, m68k_op_move_32_aw_pi, m68k_op_move_32_aw_pi, m68k_op_move_32_aw_pi, m68k_op_move_32_aw_pi, + m68k_op_move_32_aw_pd, m68k_op_move_32_aw_pd, m68k_op_move_32_aw_pd, m68k_op_move_32_aw_pd, m68k_op_move_32_aw_pd, m68k_op_move_32_aw_pd, m68k_op_move_32_aw_pd, m68k_op_move_32_aw_pd, + m68k_op_move_32_aw_di, m68k_op_move_32_aw_di, m68k_op_move_32_aw_di, m68k_op_move_32_aw_di, m68k_op_move_32_aw_di, m68k_op_move_32_aw_di, m68k_op_move_32_aw_di, m68k_op_move_32_aw_di, + m68k_op_move_32_aw_ix, m68k_op_move_32_aw_ix, m68k_op_move_32_aw_ix, m68k_op_move_32_aw_ix, m68k_op_move_32_aw_ix, m68k_op_move_32_aw_ix, m68k_op_move_32_aw_ix, m68k_op_move_32_aw_ix, + m68k_op_move_32_aw_aw, m68k_op_move_32_aw_al, m68k_op_move_32_aw_pcdi, m68k_op_move_32_aw_pcix, m68k_op_move_32_aw_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, + m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, + m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, + m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, + m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, + m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, + m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, + m68k_op_move_32_d_aw, m68k_op_move_32_d_al, m68k_op_move_32_d_pcdi, m68k_op_move_32_d_pcix, m68k_op_move_32_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, + m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, + m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, + m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, + m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, + m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, + m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, + m68k_op_movea_32_aw, m68k_op_movea_32_al, m68k_op_movea_32_pcdi, m68k_op_movea_32_pcix, m68k_op_movea_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, + m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, + m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, + m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, + m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, + m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, + m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, + m68k_op_move_32_ai_aw, m68k_op_move_32_ai_al, m68k_op_move_32_ai_pcdi, m68k_op_move_32_ai_pcix, m68k_op_move_32_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, + m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, + m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, + m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, + m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, + m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, + m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, + m68k_op_move_32_pi_aw, m68k_op_move_32_pi_al, m68k_op_move_32_pi_pcdi, m68k_op_move_32_pi_pcix, m68k_op_move_32_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, + m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, + m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, + m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, + m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, + m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, + m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, + m68k_op_move_32_pd_aw, m68k_op_move_32_pd_al, m68k_op_move_32_pd_pcdi, m68k_op_move_32_pd_pcix, m68k_op_move_32_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, + m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, + m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, + m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, + m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, + m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, + m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, + m68k_op_move_32_di_aw, m68k_op_move_32_di_al, m68k_op_move_32_di_pcdi, m68k_op_move_32_di_pcix, m68k_op_move_32_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, + m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, + m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, + m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, + m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, + m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, + m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, + m68k_op_move_32_ix_aw, m68k_op_move_32_ix_al, m68k_op_move_32_ix_pcdi, m68k_op_move_32_ix_pcix, m68k_op_move_32_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_al_d, m68k_op_move_32_al_d, m68k_op_move_32_al_d, m68k_op_move_32_al_d, m68k_op_move_32_al_d, m68k_op_move_32_al_d, m68k_op_move_32_al_d, m68k_op_move_32_al_d, + m68k_op_move_32_al_a, m68k_op_move_32_al_a, m68k_op_move_32_al_a, m68k_op_move_32_al_a, m68k_op_move_32_al_a, m68k_op_move_32_al_a, m68k_op_move_32_al_a, m68k_op_move_32_al_a, + m68k_op_move_32_al_ai, m68k_op_move_32_al_ai, m68k_op_move_32_al_ai, m68k_op_move_32_al_ai, m68k_op_move_32_al_ai, m68k_op_move_32_al_ai, m68k_op_move_32_al_ai, m68k_op_move_32_al_ai, + m68k_op_move_32_al_pi, m68k_op_move_32_al_pi, m68k_op_move_32_al_pi, m68k_op_move_32_al_pi, m68k_op_move_32_al_pi, m68k_op_move_32_al_pi, m68k_op_move_32_al_pi, m68k_op_move_32_al_pi, + m68k_op_move_32_al_pd, m68k_op_move_32_al_pd, m68k_op_move_32_al_pd, m68k_op_move_32_al_pd, m68k_op_move_32_al_pd, m68k_op_move_32_al_pd, m68k_op_move_32_al_pd, m68k_op_move_32_al_pd, + m68k_op_move_32_al_di, m68k_op_move_32_al_di, m68k_op_move_32_al_di, m68k_op_move_32_al_di, m68k_op_move_32_al_di, m68k_op_move_32_al_di, m68k_op_move_32_al_di, m68k_op_move_32_al_di, + m68k_op_move_32_al_ix, m68k_op_move_32_al_ix, m68k_op_move_32_al_ix, m68k_op_move_32_al_ix, m68k_op_move_32_al_ix, m68k_op_move_32_al_ix, m68k_op_move_32_al_ix, m68k_op_move_32_al_ix, + m68k_op_move_32_al_aw, m68k_op_move_32_al_al, m68k_op_move_32_al_pcdi, m68k_op_move_32_al_pcix, m68k_op_move_32_al_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, + m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, + m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, + m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, + m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, + m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, + m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, + m68k_op_move_32_d_aw, m68k_op_move_32_d_al, m68k_op_move_32_d_pcdi, m68k_op_move_32_d_pcix, m68k_op_move_32_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, + m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, + m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, + m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, + m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, + m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, + m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, + m68k_op_movea_32_aw, m68k_op_movea_32_al, m68k_op_movea_32_pcdi, m68k_op_movea_32_pcix, m68k_op_movea_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, + m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, + m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, + m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, + m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, + m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, + m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, + m68k_op_move_32_ai_aw, m68k_op_move_32_ai_al, m68k_op_move_32_ai_pcdi, m68k_op_move_32_ai_pcix, m68k_op_move_32_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, + m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, + m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, + m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, + m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, + m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, + m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, + m68k_op_move_32_pi_aw, m68k_op_move_32_pi_al, m68k_op_move_32_pi_pcdi, m68k_op_move_32_pi_pcix, m68k_op_move_32_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, + m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, + m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, + m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, + m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, + m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, + m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, + m68k_op_move_32_pd_aw, m68k_op_move_32_pd_al, m68k_op_move_32_pd_pcdi, m68k_op_move_32_pd_pcix, m68k_op_move_32_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, + m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, + m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, + m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, + m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, + m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, + m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, + m68k_op_move_32_di_aw, m68k_op_move_32_di_al, m68k_op_move_32_di_pcdi, m68k_op_move_32_di_pcix, m68k_op_move_32_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, + m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, + m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, + m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, + m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, + m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, + m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, + m68k_op_move_32_ix_aw, m68k_op_move_32_ix_al, m68k_op_move_32_ix_pcdi, m68k_op_move_32_ix_pcix, m68k_op_move_32_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, + m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, + m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, + m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, + m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, + m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, + m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, + m68k_op_move_32_d_aw, m68k_op_move_32_d_al, m68k_op_move_32_d_pcdi, m68k_op_move_32_d_pcix, m68k_op_move_32_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, + m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, + m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, + m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, + m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, + m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, + m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, + m68k_op_movea_32_aw, m68k_op_movea_32_al, m68k_op_movea_32_pcdi, m68k_op_movea_32_pcix, m68k_op_movea_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, + m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, + m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, + m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, + m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, + m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, + m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, + m68k_op_move_32_ai_aw, m68k_op_move_32_ai_al, m68k_op_move_32_ai_pcdi, m68k_op_move_32_ai_pcix, m68k_op_move_32_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, + m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, + m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, + m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, + m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, + m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, + m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, + m68k_op_move_32_pi_aw, m68k_op_move_32_pi_al, m68k_op_move_32_pi_pcdi, m68k_op_move_32_pi_pcix, m68k_op_move_32_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, + m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, + m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, + m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, + m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, + m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, + m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, + m68k_op_move_32_pd_aw, m68k_op_move_32_pd_al, m68k_op_move_32_pd_pcdi, m68k_op_move_32_pd_pcix, m68k_op_move_32_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, + m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, + m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, + m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, + m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, + m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, + m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, + m68k_op_move_32_di_aw, m68k_op_move_32_di_al, m68k_op_move_32_di_pcdi, m68k_op_move_32_di_pcix, m68k_op_move_32_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, + m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, + m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, + m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, + m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, + m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, + m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, + m68k_op_move_32_ix_aw, m68k_op_move_32_ix_al, m68k_op_move_32_ix_pcdi, m68k_op_move_32_ix_pcix, m68k_op_move_32_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, + m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, + m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, + m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, + m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, + m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, + m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, + m68k_op_move_32_d_aw, m68k_op_move_32_d_al, m68k_op_move_32_d_pcdi, m68k_op_move_32_d_pcix, m68k_op_move_32_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, + m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, + m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, + m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, + m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, + m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, + m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, + m68k_op_movea_32_aw, m68k_op_movea_32_al, m68k_op_movea_32_pcdi, m68k_op_movea_32_pcix, m68k_op_movea_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, + m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, + m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, + m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, + m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, + m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, + m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, + m68k_op_move_32_ai_aw, m68k_op_move_32_ai_al, m68k_op_move_32_ai_pcdi, m68k_op_move_32_ai_pcix, m68k_op_move_32_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, + m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, + m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, + m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, + m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, + m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, + m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, + m68k_op_move_32_pi_aw, m68k_op_move_32_pi_al, m68k_op_move_32_pi_pcdi, m68k_op_move_32_pi_pcix, m68k_op_move_32_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, + m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, + m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, + m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, + m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, + m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, + m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, + m68k_op_move_32_pd_aw, m68k_op_move_32_pd_al, m68k_op_move_32_pd_pcdi, m68k_op_move_32_pd_pcix, m68k_op_move_32_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, + m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, + m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, + m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, + m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, + m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, + m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, + m68k_op_move_32_di_aw, m68k_op_move_32_di_al, m68k_op_move_32_di_pcdi, m68k_op_move_32_di_pcix, m68k_op_move_32_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, + m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, + m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, + m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, + m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, + m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, + m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, + m68k_op_move_32_ix_aw, m68k_op_move_32_ix_al, m68k_op_move_32_ix_pcdi, m68k_op_move_32_ix_pcix, m68k_op_move_32_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, + m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, + m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, + m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, + m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, + m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, + m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, + m68k_op_move_32_d_aw, m68k_op_move_32_d_al, m68k_op_move_32_d_pcdi, m68k_op_move_32_d_pcix, m68k_op_move_32_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, + m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, + m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, + m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, + m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, + m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, + m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, + m68k_op_movea_32_aw, m68k_op_movea_32_al, m68k_op_movea_32_pcdi, m68k_op_movea_32_pcix, m68k_op_movea_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, + m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, + m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, + m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, + m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, + m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, + m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, + m68k_op_move_32_ai_aw, m68k_op_move_32_ai_al, m68k_op_move_32_ai_pcdi, m68k_op_move_32_ai_pcix, m68k_op_move_32_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, + m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, + m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, + m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, + m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, + m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, + m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, + m68k_op_move_32_pi_aw, m68k_op_move_32_pi_al, m68k_op_move_32_pi_pcdi, m68k_op_move_32_pi_pcix, m68k_op_move_32_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, + m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, + m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, + m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, + m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, + m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, + m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, + m68k_op_move_32_pd_aw, m68k_op_move_32_pd_al, m68k_op_move_32_pd_pcdi, m68k_op_move_32_pd_pcix, m68k_op_move_32_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, + m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, + m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, + m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, + m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, + m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, + m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, + m68k_op_move_32_di_aw, m68k_op_move_32_di_al, m68k_op_move_32_di_pcdi, m68k_op_move_32_di_pcix, m68k_op_move_32_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, + m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, + m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, + m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, + m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, + m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, + m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, + m68k_op_move_32_ix_aw, m68k_op_move_32_ix_al, m68k_op_move_32_ix_pcdi, m68k_op_move_32_ix_pcix, m68k_op_move_32_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, + m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, + m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, + m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, + m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, + m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, + m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, + m68k_op_move_32_d_aw, m68k_op_move_32_d_al, m68k_op_move_32_d_pcdi, m68k_op_move_32_d_pcix, m68k_op_move_32_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, + m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, + m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, + m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, + m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, + m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, + m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, + m68k_op_movea_32_aw, m68k_op_movea_32_al, m68k_op_movea_32_pcdi, m68k_op_movea_32_pcix, m68k_op_movea_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, + m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, + m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, + m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, + m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, + m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, + m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, + m68k_op_move_32_ai_aw, m68k_op_move_32_ai_al, m68k_op_move_32_ai_pcdi, m68k_op_move_32_ai_pcix, m68k_op_move_32_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, + m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, + m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, + m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, + m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, + m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, + m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, + m68k_op_move_32_pi_aw, m68k_op_move_32_pi_al, m68k_op_move_32_pi_pcdi, m68k_op_move_32_pi_pcix, m68k_op_move_32_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, + m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, + m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, + m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, + m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, + m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, + m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, + m68k_op_move_32_pd_aw, m68k_op_move_32_pd_al, m68k_op_move_32_pd_pcdi, m68k_op_move_32_pd_pcix, m68k_op_move_32_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, + m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, + m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, + m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, + m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, + m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, + m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, + m68k_op_move_32_di_aw, m68k_op_move_32_di_al, m68k_op_move_32_di_pcdi, m68k_op_move_32_di_pcix, m68k_op_move_32_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, + m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, + m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, + m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, + m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, + m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, + m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, + m68k_op_move_32_ix_aw, m68k_op_move_32_ix_al, m68k_op_move_32_ix_pcdi, m68k_op_move_32_ix_pcix, m68k_op_move_32_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, m68k_op_move_32_d_d, + m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, m68k_op_move_32_d_a, + m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, m68k_op_move_32_d_ai, + m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, m68k_op_move_32_d_pi, + m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, m68k_op_move_32_d_pd, + m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, m68k_op_move_32_d_di, + m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, m68k_op_move_32_d_ix, + m68k_op_move_32_d_aw, m68k_op_move_32_d_al, m68k_op_move_32_d_pcdi, m68k_op_move_32_d_pcix, m68k_op_move_32_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, m68k_op_movea_32_d, + m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, m68k_op_movea_32_a, + m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, m68k_op_movea_32_ai, + m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, m68k_op_movea_32_pi, + m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, m68k_op_movea_32_pd, + m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, m68k_op_movea_32_di, + m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, m68k_op_movea_32_ix, + m68k_op_movea_32_aw, m68k_op_movea_32_al, m68k_op_movea_32_pcdi, m68k_op_movea_32_pcix, m68k_op_movea_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, m68k_op_move_32_ai_d, + m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, m68k_op_move_32_ai_a, + m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, m68k_op_move_32_ai_ai, + m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, m68k_op_move_32_ai_pi, + m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, m68k_op_move_32_ai_pd, + m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, m68k_op_move_32_ai_di, + m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, m68k_op_move_32_ai_ix, + m68k_op_move_32_ai_aw, m68k_op_move_32_ai_al, m68k_op_move_32_ai_pcdi, m68k_op_move_32_ai_pcix, m68k_op_move_32_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, m68k_op_move_32_pi_d, + m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, m68k_op_move_32_pi_a, + m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, m68k_op_move_32_pi_ai, + m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, m68k_op_move_32_pi_pi, + m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, m68k_op_move_32_pi_pd, + m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, m68k_op_move_32_pi_di, + m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, m68k_op_move_32_pi_ix, + m68k_op_move_32_pi_aw, m68k_op_move_32_pi_al, m68k_op_move_32_pi_pcdi, m68k_op_move_32_pi_pcix, m68k_op_move_32_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, m68k_op_move_32_pd_d, + m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, m68k_op_move_32_pd_a, + m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, m68k_op_move_32_pd_ai, + m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, m68k_op_move_32_pd_pi, + m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, m68k_op_move_32_pd_pd, + m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, m68k_op_move_32_pd_di, + m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, m68k_op_move_32_pd_ix, + m68k_op_move_32_pd_aw, m68k_op_move_32_pd_al, m68k_op_move_32_pd_pcdi, m68k_op_move_32_pd_pcix, m68k_op_move_32_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, m68k_op_move_32_di_d, + m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, m68k_op_move_32_di_a, + m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, m68k_op_move_32_di_ai, + m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, m68k_op_move_32_di_pi, + m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, m68k_op_move_32_di_pd, + m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, m68k_op_move_32_di_di, + m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, m68k_op_move_32_di_ix, + m68k_op_move_32_di_aw, m68k_op_move_32_di_al, m68k_op_move_32_di_pcdi, m68k_op_move_32_di_pcix, m68k_op_move_32_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, m68k_op_move_32_ix_d, + m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, m68k_op_move_32_ix_a, + m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, m68k_op_move_32_ix_ai, + m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, m68k_op_move_32_ix_pi, + m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, m68k_op_move_32_ix_pd, + m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, m68k_op_move_32_ix_di, + m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, m68k_op_move_32_ix_ix, + m68k_op_move_32_ix_aw, m68k_op_move_32_ix_al, m68k_op_move_32_ix_pcdi, m68k_op_move_32_ix_pcix, m68k_op_move_32_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, + m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, + m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, + m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, + m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, + m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, + m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, + m68k_op_move_16_d_aw, m68k_op_move_16_d_al, m68k_op_move_16_d_pcdi, m68k_op_move_16_d_pcix, m68k_op_move_16_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, + m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, + m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, + m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, + m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, + m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, + m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, + m68k_op_movea_16_aw, m68k_op_movea_16_al, m68k_op_movea_16_pcdi, m68k_op_movea_16_pcix, m68k_op_movea_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, + m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, + m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, + m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, + m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, + m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, + m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, + m68k_op_move_16_ai_aw, m68k_op_move_16_ai_al, m68k_op_move_16_ai_pcdi, m68k_op_move_16_ai_pcix, m68k_op_move_16_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, + m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, + m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, + m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, + m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, + m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, + m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, + m68k_op_move_16_pi_aw, m68k_op_move_16_pi_al, m68k_op_move_16_pi_pcdi, m68k_op_move_16_pi_pcix, m68k_op_move_16_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, + m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, + m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, + m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, + m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, + m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, + m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, + m68k_op_move_16_pd_aw, m68k_op_move_16_pd_al, m68k_op_move_16_pd_pcdi, m68k_op_move_16_pd_pcix, m68k_op_move_16_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, + m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, + m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, + m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, + m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, + m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, + m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, + m68k_op_move_16_di_aw, m68k_op_move_16_di_al, m68k_op_move_16_di_pcdi, m68k_op_move_16_di_pcix, m68k_op_move_16_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, + m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, + m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, + m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, + m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, + m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, + m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, + m68k_op_move_16_ix_aw, m68k_op_move_16_ix_al, m68k_op_move_16_ix_pcdi, m68k_op_move_16_ix_pcix, m68k_op_move_16_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_aw_d, m68k_op_move_16_aw_d, m68k_op_move_16_aw_d, m68k_op_move_16_aw_d, m68k_op_move_16_aw_d, m68k_op_move_16_aw_d, m68k_op_move_16_aw_d, m68k_op_move_16_aw_d, + m68k_op_move_16_aw_a, m68k_op_move_16_aw_a, m68k_op_move_16_aw_a, m68k_op_move_16_aw_a, m68k_op_move_16_aw_a, m68k_op_move_16_aw_a, m68k_op_move_16_aw_a, m68k_op_move_16_aw_a, + m68k_op_move_16_aw_ai, m68k_op_move_16_aw_ai, m68k_op_move_16_aw_ai, m68k_op_move_16_aw_ai, m68k_op_move_16_aw_ai, m68k_op_move_16_aw_ai, m68k_op_move_16_aw_ai, m68k_op_move_16_aw_ai, + m68k_op_move_16_aw_pi, m68k_op_move_16_aw_pi, m68k_op_move_16_aw_pi, m68k_op_move_16_aw_pi, m68k_op_move_16_aw_pi, m68k_op_move_16_aw_pi, m68k_op_move_16_aw_pi, m68k_op_move_16_aw_pi, + m68k_op_move_16_aw_pd, m68k_op_move_16_aw_pd, m68k_op_move_16_aw_pd, m68k_op_move_16_aw_pd, m68k_op_move_16_aw_pd, m68k_op_move_16_aw_pd, m68k_op_move_16_aw_pd, m68k_op_move_16_aw_pd, + m68k_op_move_16_aw_di, m68k_op_move_16_aw_di, m68k_op_move_16_aw_di, m68k_op_move_16_aw_di, m68k_op_move_16_aw_di, m68k_op_move_16_aw_di, m68k_op_move_16_aw_di, m68k_op_move_16_aw_di, + m68k_op_move_16_aw_ix, m68k_op_move_16_aw_ix, m68k_op_move_16_aw_ix, m68k_op_move_16_aw_ix, m68k_op_move_16_aw_ix, m68k_op_move_16_aw_ix, m68k_op_move_16_aw_ix, m68k_op_move_16_aw_ix, + m68k_op_move_16_aw_aw, m68k_op_move_16_aw_al, m68k_op_move_16_aw_pcdi, m68k_op_move_16_aw_pcix, m68k_op_move_16_aw_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, + m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, + m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, + m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, + m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, + m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, + m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, + m68k_op_move_16_d_aw, m68k_op_move_16_d_al, m68k_op_move_16_d_pcdi, m68k_op_move_16_d_pcix, m68k_op_move_16_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, + m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, + m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, + m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, + m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, + m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, + m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, + m68k_op_movea_16_aw, m68k_op_movea_16_al, m68k_op_movea_16_pcdi, m68k_op_movea_16_pcix, m68k_op_movea_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, + m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, + m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, + m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, + m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, + m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, + m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, + m68k_op_move_16_ai_aw, m68k_op_move_16_ai_al, m68k_op_move_16_ai_pcdi, m68k_op_move_16_ai_pcix, m68k_op_move_16_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, + m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, + m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, + m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, + m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, + m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, + m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, + m68k_op_move_16_pi_aw, m68k_op_move_16_pi_al, m68k_op_move_16_pi_pcdi, m68k_op_move_16_pi_pcix, m68k_op_move_16_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, + m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, + m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, + m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, + m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, + m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, + m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, + m68k_op_move_16_pd_aw, m68k_op_move_16_pd_al, m68k_op_move_16_pd_pcdi, m68k_op_move_16_pd_pcix, m68k_op_move_16_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, + m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, + m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, + m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, + m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, + m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, + m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, + m68k_op_move_16_di_aw, m68k_op_move_16_di_al, m68k_op_move_16_di_pcdi, m68k_op_move_16_di_pcix, m68k_op_move_16_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, + m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, + m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, + m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, + m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, + m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, + m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, + m68k_op_move_16_ix_aw, m68k_op_move_16_ix_al, m68k_op_move_16_ix_pcdi, m68k_op_move_16_ix_pcix, m68k_op_move_16_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_al_d, m68k_op_move_16_al_d, m68k_op_move_16_al_d, m68k_op_move_16_al_d, m68k_op_move_16_al_d, m68k_op_move_16_al_d, m68k_op_move_16_al_d, m68k_op_move_16_al_d, + m68k_op_move_16_al_a, m68k_op_move_16_al_a, m68k_op_move_16_al_a, m68k_op_move_16_al_a, m68k_op_move_16_al_a, m68k_op_move_16_al_a, m68k_op_move_16_al_a, m68k_op_move_16_al_a, + m68k_op_move_16_al_ai, m68k_op_move_16_al_ai, m68k_op_move_16_al_ai, m68k_op_move_16_al_ai, m68k_op_move_16_al_ai, m68k_op_move_16_al_ai, m68k_op_move_16_al_ai, m68k_op_move_16_al_ai, + m68k_op_move_16_al_pi, m68k_op_move_16_al_pi, m68k_op_move_16_al_pi, m68k_op_move_16_al_pi, m68k_op_move_16_al_pi, m68k_op_move_16_al_pi, m68k_op_move_16_al_pi, m68k_op_move_16_al_pi, + m68k_op_move_16_al_pd, m68k_op_move_16_al_pd, m68k_op_move_16_al_pd, m68k_op_move_16_al_pd, m68k_op_move_16_al_pd, m68k_op_move_16_al_pd, m68k_op_move_16_al_pd, m68k_op_move_16_al_pd, + m68k_op_move_16_al_di, m68k_op_move_16_al_di, m68k_op_move_16_al_di, m68k_op_move_16_al_di, m68k_op_move_16_al_di, m68k_op_move_16_al_di, m68k_op_move_16_al_di, m68k_op_move_16_al_di, + m68k_op_move_16_al_ix, m68k_op_move_16_al_ix, m68k_op_move_16_al_ix, m68k_op_move_16_al_ix, m68k_op_move_16_al_ix, m68k_op_move_16_al_ix, m68k_op_move_16_al_ix, m68k_op_move_16_al_ix, + m68k_op_move_16_al_aw, m68k_op_move_16_al_al, m68k_op_move_16_al_pcdi, m68k_op_move_16_al_pcix, m68k_op_move_16_al_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, + m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, + m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, + m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, + m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, + m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, + m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, + m68k_op_move_16_d_aw, m68k_op_move_16_d_al, m68k_op_move_16_d_pcdi, m68k_op_move_16_d_pcix, m68k_op_move_16_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, + m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, + m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, + m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, + m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, + m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, + m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, + m68k_op_movea_16_aw, m68k_op_movea_16_al, m68k_op_movea_16_pcdi, m68k_op_movea_16_pcix, m68k_op_movea_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, + m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, + m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, + m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, + m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, + m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, + m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, + m68k_op_move_16_ai_aw, m68k_op_move_16_ai_al, m68k_op_move_16_ai_pcdi, m68k_op_move_16_ai_pcix, m68k_op_move_16_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, + m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, + m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, + m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, + m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, + m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, + m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, + m68k_op_move_16_pi_aw, m68k_op_move_16_pi_al, m68k_op_move_16_pi_pcdi, m68k_op_move_16_pi_pcix, m68k_op_move_16_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, + m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, + m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, + m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, + m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, + m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, + m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, + m68k_op_move_16_pd_aw, m68k_op_move_16_pd_al, m68k_op_move_16_pd_pcdi, m68k_op_move_16_pd_pcix, m68k_op_move_16_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, + m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, + m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, + m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, + m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, + m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, + m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, + m68k_op_move_16_di_aw, m68k_op_move_16_di_al, m68k_op_move_16_di_pcdi, m68k_op_move_16_di_pcix, m68k_op_move_16_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, + m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, + m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, + m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, + m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, + m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, + m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, + m68k_op_move_16_ix_aw, m68k_op_move_16_ix_al, m68k_op_move_16_ix_pcdi, m68k_op_move_16_ix_pcix, m68k_op_move_16_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, + m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, + m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, + m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, + m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, + m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, + m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, + m68k_op_move_16_d_aw, m68k_op_move_16_d_al, m68k_op_move_16_d_pcdi, m68k_op_move_16_d_pcix, m68k_op_move_16_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, + m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, + m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, + m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, + m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, + m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, + m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, + m68k_op_movea_16_aw, m68k_op_movea_16_al, m68k_op_movea_16_pcdi, m68k_op_movea_16_pcix, m68k_op_movea_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, + m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, + m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, + m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, + m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, + m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, + m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, + m68k_op_move_16_ai_aw, m68k_op_move_16_ai_al, m68k_op_move_16_ai_pcdi, m68k_op_move_16_ai_pcix, m68k_op_move_16_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, + m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, + m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, + m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, + m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, + m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, + m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, + m68k_op_move_16_pi_aw, m68k_op_move_16_pi_al, m68k_op_move_16_pi_pcdi, m68k_op_move_16_pi_pcix, m68k_op_move_16_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, + m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, + m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, + m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, + m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, + m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, + m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, + m68k_op_move_16_pd_aw, m68k_op_move_16_pd_al, m68k_op_move_16_pd_pcdi, m68k_op_move_16_pd_pcix, m68k_op_move_16_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, + m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, + m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, + m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, + m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, + m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, + m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, + m68k_op_move_16_di_aw, m68k_op_move_16_di_al, m68k_op_move_16_di_pcdi, m68k_op_move_16_di_pcix, m68k_op_move_16_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, + m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, + m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, + m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, + m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, + m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, + m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, + m68k_op_move_16_ix_aw, m68k_op_move_16_ix_al, m68k_op_move_16_ix_pcdi, m68k_op_move_16_ix_pcix, m68k_op_move_16_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, + m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, + m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, + m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, + m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, + m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, + m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, + m68k_op_move_16_d_aw, m68k_op_move_16_d_al, m68k_op_move_16_d_pcdi, m68k_op_move_16_d_pcix, m68k_op_move_16_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, + m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, + m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, + m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, + m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, + m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, + m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, + m68k_op_movea_16_aw, m68k_op_movea_16_al, m68k_op_movea_16_pcdi, m68k_op_movea_16_pcix, m68k_op_movea_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, + m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, + m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, + m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, + m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, + m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, + m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, + m68k_op_move_16_ai_aw, m68k_op_move_16_ai_al, m68k_op_move_16_ai_pcdi, m68k_op_move_16_ai_pcix, m68k_op_move_16_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, + m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, + m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, + m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, + m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, + m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, + m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, + m68k_op_move_16_pi_aw, m68k_op_move_16_pi_al, m68k_op_move_16_pi_pcdi, m68k_op_move_16_pi_pcix, m68k_op_move_16_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, + m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, + m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, + m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, + m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, + m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, + m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, + m68k_op_move_16_pd_aw, m68k_op_move_16_pd_al, m68k_op_move_16_pd_pcdi, m68k_op_move_16_pd_pcix, m68k_op_move_16_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, + m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, + m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, + m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, + m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, + m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, + m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, + m68k_op_move_16_di_aw, m68k_op_move_16_di_al, m68k_op_move_16_di_pcdi, m68k_op_move_16_di_pcix, m68k_op_move_16_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, + m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, + m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, + m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, + m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, + m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, + m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, + m68k_op_move_16_ix_aw, m68k_op_move_16_ix_al, m68k_op_move_16_ix_pcdi, m68k_op_move_16_ix_pcix, m68k_op_move_16_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, + m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, + m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, + m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, + m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, + m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, + m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, + m68k_op_move_16_d_aw, m68k_op_move_16_d_al, m68k_op_move_16_d_pcdi, m68k_op_move_16_d_pcix, m68k_op_move_16_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, + m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, + m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, + m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, + m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, + m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, + m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, + m68k_op_movea_16_aw, m68k_op_movea_16_al, m68k_op_movea_16_pcdi, m68k_op_movea_16_pcix, m68k_op_movea_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, + m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, + m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, + m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, + m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, + m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, + m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, + m68k_op_move_16_ai_aw, m68k_op_move_16_ai_al, m68k_op_move_16_ai_pcdi, m68k_op_move_16_ai_pcix, m68k_op_move_16_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, + m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, + m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, + m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, + m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, + m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, + m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, + m68k_op_move_16_pi_aw, m68k_op_move_16_pi_al, m68k_op_move_16_pi_pcdi, m68k_op_move_16_pi_pcix, m68k_op_move_16_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, + m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, + m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, + m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, + m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, + m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, + m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, + m68k_op_move_16_pd_aw, m68k_op_move_16_pd_al, m68k_op_move_16_pd_pcdi, m68k_op_move_16_pd_pcix, m68k_op_move_16_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, + m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, + m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, + m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, + m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, + m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, + m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, + m68k_op_move_16_di_aw, m68k_op_move_16_di_al, m68k_op_move_16_di_pcdi, m68k_op_move_16_di_pcix, m68k_op_move_16_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, + m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, + m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, + m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, + m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, + m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, + m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, + m68k_op_move_16_ix_aw, m68k_op_move_16_ix_al, m68k_op_move_16_ix_pcdi, m68k_op_move_16_ix_pcix, m68k_op_move_16_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, + m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, + m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, + m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, + m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, + m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, + m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, + m68k_op_move_16_d_aw, m68k_op_move_16_d_al, m68k_op_move_16_d_pcdi, m68k_op_move_16_d_pcix, m68k_op_move_16_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, + m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, + m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, + m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, + m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, + m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, + m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, + m68k_op_movea_16_aw, m68k_op_movea_16_al, m68k_op_movea_16_pcdi, m68k_op_movea_16_pcix, m68k_op_movea_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, + m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, + m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, + m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, + m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, + m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, + m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, + m68k_op_move_16_ai_aw, m68k_op_move_16_ai_al, m68k_op_move_16_ai_pcdi, m68k_op_move_16_ai_pcix, m68k_op_move_16_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, + m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, + m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, + m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, + m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, + m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, + m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, + m68k_op_move_16_pi_aw, m68k_op_move_16_pi_al, m68k_op_move_16_pi_pcdi, m68k_op_move_16_pi_pcix, m68k_op_move_16_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, + m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, + m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, + m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, + m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, + m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, + m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, + m68k_op_move_16_pd_aw, m68k_op_move_16_pd_al, m68k_op_move_16_pd_pcdi, m68k_op_move_16_pd_pcix, m68k_op_move_16_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, + m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, + m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, + m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, + m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, + m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, + m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, + m68k_op_move_16_di_aw, m68k_op_move_16_di_al, m68k_op_move_16_di_pcdi, m68k_op_move_16_di_pcix, m68k_op_move_16_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, + m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, + m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, + m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, + m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, + m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, + m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, + m68k_op_move_16_ix_aw, m68k_op_move_16_ix_al, m68k_op_move_16_ix_pcdi, m68k_op_move_16_ix_pcix, m68k_op_move_16_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, m68k_op_move_16_d_d, + m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, m68k_op_move_16_d_a, + m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, m68k_op_move_16_d_ai, + m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, m68k_op_move_16_d_pi, + m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, m68k_op_move_16_d_pd, + m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, m68k_op_move_16_d_di, + m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, m68k_op_move_16_d_ix, + m68k_op_move_16_d_aw, m68k_op_move_16_d_al, m68k_op_move_16_d_pcdi, m68k_op_move_16_d_pcix, m68k_op_move_16_d_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, m68k_op_movea_16_d, + m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, m68k_op_movea_16_a, + m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, m68k_op_movea_16_ai, + m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, m68k_op_movea_16_pi, + m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, m68k_op_movea_16_pd, + m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, m68k_op_movea_16_di, + m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, m68k_op_movea_16_ix, + m68k_op_movea_16_aw, m68k_op_movea_16_al, m68k_op_movea_16_pcdi, m68k_op_movea_16_pcix, m68k_op_movea_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, m68k_op_move_16_ai_d, + m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, m68k_op_move_16_ai_a, + m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, m68k_op_move_16_ai_ai, + m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, m68k_op_move_16_ai_pi, + m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, m68k_op_move_16_ai_pd, + m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, m68k_op_move_16_ai_di, + m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, m68k_op_move_16_ai_ix, + m68k_op_move_16_ai_aw, m68k_op_move_16_ai_al, m68k_op_move_16_ai_pcdi, m68k_op_move_16_ai_pcix, m68k_op_move_16_ai_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, m68k_op_move_16_pi_d, + m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, m68k_op_move_16_pi_a, + m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, m68k_op_move_16_pi_ai, + m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, m68k_op_move_16_pi_pi, + m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, m68k_op_move_16_pi_pd, + m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, m68k_op_move_16_pi_di, + m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, m68k_op_move_16_pi_ix, + m68k_op_move_16_pi_aw, m68k_op_move_16_pi_al, m68k_op_move_16_pi_pcdi, m68k_op_move_16_pi_pcix, m68k_op_move_16_pi_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, m68k_op_move_16_pd_d, + m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, m68k_op_move_16_pd_a, + m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, m68k_op_move_16_pd_ai, + m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, m68k_op_move_16_pd_pi, + m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, m68k_op_move_16_pd_pd, + m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, m68k_op_move_16_pd_di, + m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, m68k_op_move_16_pd_ix, + m68k_op_move_16_pd_aw, m68k_op_move_16_pd_al, m68k_op_move_16_pd_pcdi, m68k_op_move_16_pd_pcix, m68k_op_move_16_pd_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, m68k_op_move_16_di_d, + m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, m68k_op_move_16_di_a, + m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, m68k_op_move_16_di_ai, + m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, m68k_op_move_16_di_pi, + m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, m68k_op_move_16_di_pd, + m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, m68k_op_move_16_di_di, + m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, m68k_op_move_16_di_ix, + m68k_op_move_16_di_aw, m68k_op_move_16_di_al, m68k_op_move_16_di_pcdi, m68k_op_move_16_di_pcix, m68k_op_move_16_di_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, m68k_op_move_16_ix_d, + m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, m68k_op_move_16_ix_a, + m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, m68k_op_move_16_ix_ai, + m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, m68k_op_move_16_ix_pi, + m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, m68k_op_move_16_ix_pd, + m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, m68k_op_move_16_ix_di, + m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, m68k_op_move_16_ix_ix, + m68k_op_move_16_ix_aw, m68k_op_move_16_ix_al, m68k_op_move_16_ix_pcdi, m68k_op_move_16_ix_pcix, m68k_op_move_16_ix_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_negx_8_d, m68k_op_negx_8_d, m68k_op_negx_8_d, m68k_op_negx_8_d, m68k_op_negx_8_d, m68k_op_negx_8_d, m68k_op_negx_8_d, m68k_op_negx_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_negx_8_ai, m68k_op_negx_8_ai, m68k_op_negx_8_ai, m68k_op_negx_8_ai, m68k_op_negx_8_ai, m68k_op_negx_8_ai, m68k_op_negx_8_ai, m68k_op_negx_8_ai, + m68k_op_negx_8_pi, m68k_op_negx_8_pi, m68k_op_negx_8_pi, m68k_op_negx_8_pi, m68k_op_negx_8_pi, m68k_op_negx_8_pi, m68k_op_negx_8_pi, m68k_op_negx_8_pi7, + m68k_op_negx_8_pd, m68k_op_negx_8_pd, m68k_op_negx_8_pd, m68k_op_negx_8_pd, m68k_op_negx_8_pd, m68k_op_negx_8_pd, m68k_op_negx_8_pd, m68k_op_negx_8_pd7, + m68k_op_negx_8_di, m68k_op_negx_8_di, m68k_op_negx_8_di, m68k_op_negx_8_di, m68k_op_negx_8_di, m68k_op_negx_8_di, m68k_op_negx_8_di, m68k_op_negx_8_di, + m68k_op_negx_8_ix, m68k_op_negx_8_ix, m68k_op_negx_8_ix, m68k_op_negx_8_ix, m68k_op_negx_8_ix, m68k_op_negx_8_ix, m68k_op_negx_8_ix, m68k_op_negx_8_ix, + m68k_op_negx_8_aw, m68k_op_negx_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_negx_16_d, m68k_op_negx_16_d, m68k_op_negx_16_d, m68k_op_negx_16_d, m68k_op_negx_16_d, m68k_op_negx_16_d, m68k_op_negx_16_d, m68k_op_negx_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_negx_16_ai, m68k_op_negx_16_ai, m68k_op_negx_16_ai, m68k_op_negx_16_ai, m68k_op_negx_16_ai, m68k_op_negx_16_ai, m68k_op_negx_16_ai, m68k_op_negx_16_ai, + m68k_op_negx_16_pi, m68k_op_negx_16_pi, m68k_op_negx_16_pi, m68k_op_negx_16_pi, m68k_op_negx_16_pi, m68k_op_negx_16_pi, m68k_op_negx_16_pi, m68k_op_negx_16_pi, + m68k_op_negx_16_pd, m68k_op_negx_16_pd, m68k_op_negx_16_pd, m68k_op_negx_16_pd, m68k_op_negx_16_pd, m68k_op_negx_16_pd, m68k_op_negx_16_pd, m68k_op_negx_16_pd, + m68k_op_negx_16_di, m68k_op_negx_16_di, m68k_op_negx_16_di, m68k_op_negx_16_di, m68k_op_negx_16_di, m68k_op_negx_16_di, m68k_op_negx_16_di, m68k_op_negx_16_di, + m68k_op_negx_16_ix, m68k_op_negx_16_ix, m68k_op_negx_16_ix, m68k_op_negx_16_ix, m68k_op_negx_16_ix, m68k_op_negx_16_ix, m68k_op_negx_16_ix, m68k_op_negx_16_ix, + m68k_op_negx_16_aw, m68k_op_negx_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_negx_32_d, m68k_op_negx_32_d, m68k_op_negx_32_d, m68k_op_negx_32_d, m68k_op_negx_32_d, m68k_op_negx_32_d, m68k_op_negx_32_d, m68k_op_negx_32_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_negx_32_ai, m68k_op_negx_32_ai, m68k_op_negx_32_ai, m68k_op_negx_32_ai, m68k_op_negx_32_ai, m68k_op_negx_32_ai, m68k_op_negx_32_ai, m68k_op_negx_32_ai, + m68k_op_negx_32_pi, m68k_op_negx_32_pi, m68k_op_negx_32_pi, m68k_op_negx_32_pi, m68k_op_negx_32_pi, m68k_op_negx_32_pi, m68k_op_negx_32_pi, m68k_op_negx_32_pi, + m68k_op_negx_32_pd, m68k_op_negx_32_pd, m68k_op_negx_32_pd, m68k_op_negx_32_pd, m68k_op_negx_32_pd, m68k_op_negx_32_pd, m68k_op_negx_32_pd, m68k_op_negx_32_pd, + m68k_op_negx_32_di, m68k_op_negx_32_di, m68k_op_negx_32_di, m68k_op_negx_32_di, m68k_op_negx_32_di, m68k_op_negx_32_di, m68k_op_negx_32_di, m68k_op_negx_32_di, + m68k_op_negx_32_ix, m68k_op_negx_32_ix, m68k_op_negx_32_ix, m68k_op_negx_32_ix, m68k_op_negx_32_ix, m68k_op_negx_32_ix, m68k_op_negx_32_ix, m68k_op_negx_32_ix, + m68k_op_negx_32_aw, m68k_op_negx_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_frs_d, m68k_op_move_16_frs_d, m68k_op_move_16_frs_d, m68k_op_move_16_frs_d, m68k_op_move_16_frs_d, m68k_op_move_16_frs_d, m68k_op_move_16_frs_d, m68k_op_move_16_frs_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_frs_ai, m68k_op_move_16_frs_ai, m68k_op_move_16_frs_ai, m68k_op_move_16_frs_ai, m68k_op_move_16_frs_ai, m68k_op_move_16_frs_ai, m68k_op_move_16_frs_ai, m68k_op_move_16_frs_ai, + m68k_op_move_16_frs_pi, m68k_op_move_16_frs_pi, m68k_op_move_16_frs_pi, m68k_op_move_16_frs_pi, m68k_op_move_16_frs_pi, m68k_op_move_16_frs_pi, m68k_op_move_16_frs_pi, m68k_op_move_16_frs_pi, + m68k_op_move_16_frs_pd, m68k_op_move_16_frs_pd, m68k_op_move_16_frs_pd, m68k_op_move_16_frs_pd, m68k_op_move_16_frs_pd, m68k_op_move_16_frs_pd, m68k_op_move_16_frs_pd, m68k_op_move_16_frs_pd, + m68k_op_move_16_frs_di, m68k_op_move_16_frs_di, m68k_op_move_16_frs_di, m68k_op_move_16_frs_di, m68k_op_move_16_frs_di, m68k_op_move_16_frs_di, m68k_op_move_16_frs_di, m68k_op_move_16_frs_di, + m68k_op_move_16_frs_ix, m68k_op_move_16_frs_ix, m68k_op_move_16_frs_ix, m68k_op_move_16_frs_ix, m68k_op_move_16_frs_ix, m68k_op_move_16_frs_ix, m68k_op_move_16_frs_ix, m68k_op_move_16_frs_ix, + m68k_op_move_16_frs_aw, m68k_op_move_16_frs_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, + m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, + m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, + m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, + m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, + m68k_op_chk_16_aw, m68k_op_chk_16_al, m68k_op_chk_16_pcdi, m68k_op_chk_16_pcix, m68k_op_chk_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, + m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, + m68k_op_lea_32_aw, m68k_op_lea_32_al, m68k_op_lea_32_pcdi, m68k_op_lea_32_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_clr_8_d, m68k_op_clr_8_d, m68k_op_clr_8_d, m68k_op_clr_8_d, m68k_op_clr_8_d, m68k_op_clr_8_d, m68k_op_clr_8_d, m68k_op_clr_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_clr_8_ai, m68k_op_clr_8_ai, m68k_op_clr_8_ai, m68k_op_clr_8_ai, m68k_op_clr_8_ai, m68k_op_clr_8_ai, m68k_op_clr_8_ai, m68k_op_clr_8_ai, + m68k_op_clr_8_pi, m68k_op_clr_8_pi, m68k_op_clr_8_pi, m68k_op_clr_8_pi, m68k_op_clr_8_pi, m68k_op_clr_8_pi, m68k_op_clr_8_pi, m68k_op_clr_8_pi7, + m68k_op_clr_8_pd, m68k_op_clr_8_pd, m68k_op_clr_8_pd, m68k_op_clr_8_pd, m68k_op_clr_8_pd, m68k_op_clr_8_pd, m68k_op_clr_8_pd, m68k_op_clr_8_pd7, + m68k_op_clr_8_di, m68k_op_clr_8_di, m68k_op_clr_8_di, m68k_op_clr_8_di, m68k_op_clr_8_di, m68k_op_clr_8_di, m68k_op_clr_8_di, m68k_op_clr_8_di, + m68k_op_clr_8_ix, m68k_op_clr_8_ix, m68k_op_clr_8_ix, m68k_op_clr_8_ix, m68k_op_clr_8_ix, m68k_op_clr_8_ix, m68k_op_clr_8_ix, m68k_op_clr_8_ix, + m68k_op_clr_8_aw, m68k_op_clr_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_clr_16_d, m68k_op_clr_16_d, m68k_op_clr_16_d, m68k_op_clr_16_d, m68k_op_clr_16_d, m68k_op_clr_16_d, m68k_op_clr_16_d, m68k_op_clr_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_clr_16_ai, m68k_op_clr_16_ai, m68k_op_clr_16_ai, m68k_op_clr_16_ai, m68k_op_clr_16_ai, m68k_op_clr_16_ai, m68k_op_clr_16_ai, m68k_op_clr_16_ai, + m68k_op_clr_16_pi, m68k_op_clr_16_pi, m68k_op_clr_16_pi, m68k_op_clr_16_pi, m68k_op_clr_16_pi, m68k_op_clr_16_pi, m68k_op_clr_16_pi, m68k_op_clr_16_pi, + m68k_op_clr_16_pd, m68k_op_clr_16_pd, m68k_op_clr_16_pd, m68k_op_clr_16_pd, m68k_op_clr_16_pd, m68k_op_clr_16_pd, m68k_op_clr_16_pd, m68k_op_clr_16_pd, + m68k_op_clr_16_di, m68k_op_clr_16_di, m68k_op_clr_16_di, m68k_op_clr_16_di, m68k_op_clr_16_di, m68k_op_clr_16_di, m68k_op_clr_16_di, m68k_op_clr_16_di, + m68k_op_clr_16_ix, m68k_op_clr_16_ix, m68k_op_clr_16_ix, m68k_op_clr_16_ix, m68k_op_clr_16_ix, m68k_op_clr_16_ix, m68k_op_clr_16_ix, m68k_op_clr_16_ix, + m68k_op_clr_16_aw, m68k_op_clr_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_clr_32_d, m68k_op_clr_32_d, m68k_op_clr_32_d, m68k_op_clr_32_d, m68k_op_clr_32_d, m68k_op_clr_32_d, m68k_op_clr_32_d, m68k_op_clr_32_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_clr_32_ai, m68k_op_clr_32_ai, m68k_op_clr_32_ai, m68k_op_clr_32_ai, m68k_op_clr_32_ai, m68k_op_clr_32_ai, m68k_op_clr_32_ai, m68k_op_clr_32_ai, + m68k_op_clr_32_pi, m68k_op_clr_32_pi, m68k_op_clr_32_pi, m68k_op_clr_32_pi, m68k_op_clr_32_pi, m68k_op_clr_32_pi, m68k_op_clr_32_pi, m68k_op_clr_32_pi, + m68k_op_clr_32_pd, m68k_op_clr_32_pd, m68k_op_clr_32_pd, m68k_op_clr_32_pd, m68k_op_clr_32_pd, m68k_op_clr_32_pd, m68k_op_clr_32_pd, m68k_op_clr_32_pd, + m68k_op_clr_32_di, m68k_op_clr_32_di, m68k_op_clr_32_di, m68k_op_clr_32_di, m68k_op_clr_32_di, m68k_op_clr_32_di, m68k_op_clr_32_di, m68k_op_clr_32_di, + m68k_op_clr_32_ix, m68k_op_clr_32_ix, m68k_op_clr_32_ix, m68k_op_clr_32_ix, m68k_op_clr_32_ix, m68k_op_clr_32_ix, m68k_op_clr_32_ix, m68k_op_clr_32_ix, + m68k_op_clr_32_aw, m68k_op_clr_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, + m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, + m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, + m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, + m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, + m68k_op_chk_16_aw, m68k_op_chk_16_al, m68k_op_chk_16_pcdi, m68k_op_chk_16_pcix, m68k_op_chk_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, + m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, + m68k_op_lea_32_aw, m68k_op_lea_32_al, m68k_op_lea_32_pcdi, m68k_op_lea_32_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_neg_8_d, m68k_op_neg_8_d, m68k_op_neg_8_d, m68k_op_neg_8_d, m68k_op_neg_8_d, m68k_op_neg_8_d, m68k_op_neg_8_d, m68k_op_neg_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_neg_8_ai, m68k_op_neg_8_ai, m68k_op_neg_8_ai, m68k_op_neg_8_ai, m68k_op_neg_8_ai, m68k_op_neg_8_ai, m68k_op_neg_8_ai, m68k_op_neg_8_ai, + m68k_op_neg_8_pi, m68k_op_neg_8_pi, m68k_op_neg_8_pi, m68k_op_neg_8_pi, m68k_op_neg_8_pi, m68k_op_neg_8_pi, m68k_op_neg_8_pi, m68k_op_neg_8_pi7, + m68k_op_neg_8_pd, m68k_op_neg_8_pd, m68k_op_neg_8_pd, m68k_op_neg_8_pd, m68k_op_neg_8_pd, m68k_op_neg_8_pd, m68k_op_neg_8_pd, m68k_op_neg_8_pd7, + m68k_op_neg_8_di, m68k_op_neg_8_di, m68k_op_neg_8_di, m68k_op_neg_8_di, m68k_op_neg_8_di, m68k_op_neg_8_di, m68k_op_neg_8_di, m68k_op_neg_8_di, + m68k_op_neg_8_ix, m68k_op_neg_8_ix, m68k_op_neg_8_ix, m68k_op_neg_8_ix, m68k_op_neg_8_ix, m68k_op_neg_8_ix, m68k_op_neg_8_ix, m68k_op_neg_8_ix, + m68k_op_neg_8_aw, m68k_op_neg_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_neg_16_d, m68k_op_neg_16_d, m68k_op_neg_16_d, m68k_op_neg_16_d, m68k_op_neg_16_d, m68k_op_neg_16_d, m68k_op_neg_16_d, m68k_op_neg_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_neg_16_ai, m68k_op_neg_16_ai, m68k_op_neg_16_ai, m68k_op_neg_16_ai, m68k_op_neg_16_ai, m68k_op_neg_16_ai, m68k_op_neg_16_ai, m68k_op_neg_16_ai, + m68k_op_neg_16_pi, m68k_op_neg_16_pi, m68k_op_neg_16_pi, m68k_op_neg_16_pi, m68k_op_neg_16_pi, m68k_op_neg_16_pi, m68k_op_neg_16_pi, m68k_op_neg_16_pi, + m68k_op_neg_16_pd, m68k_op_neg_16_pd, m68k_op_neg_16_pd, m68k_op_neg_16_pd, m68k_op_neg_16_pd, m68k_op_neg_16_pd, m68k_op_neg_16_pd, m68k_op_neg_16_pd, + m68k_op_neg_16_di, m68k_op_neg_16_di, m68k_op_neg_16_di, m68k_op_neg_16_di, m68k_op_neg_16_di, m68k_op_neg_16_di, m68k_op_neg_16_di, m68k_op_neg_16_di, + m68k_op_neg_16_ix, m68k_op_neg_16_ix, m68k_op_neg_16_ix, m68k_op_neg_16_ix, m68k_op_neg_16_ix, m68k_op_neg_16_ix, m68k_op_neg_16_ix, m68k_op_neg_16_ix, + m68k_op_neg_16_aw, m68k_op_neg_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_neg_32_d, m68k_op_neg_32_d, m68k_op_neg_32_d, m68k_op_neg_32_d, m68k_op_neg_32_d, m68k_op_neg_32_d, m68k_op_neg_32_d, m68k_op_neg_32_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_neg_32_ai, m68k_op_neg_32_ai, m68k_op_neg_32_ai, m68k_op_neg_32_ai, m68k_op_neg_32_ai, m68k_op_neg_32_ai, m68k_op_neg_32_ai, m68k_op_neg_32_ai, + m68k_op_neg_32_pi, m68k_op_neg_32_pi, m68k_op_neg_32_pi, m68k_op_neg_32_pi, m68k_op_neg_32_pi, m68k_op_neg_32_pi, m68k_op_neg_32_pi, m68k_op_neg_32_pi, + m68k_op_neg_32_pd, m68k_op_neg_32_pd, m68k_op_neg_32_pd, m68k_op_neg_32_pd, m68k_op_neg_32_pd, m68k_op_neg_32_pd, m68k_op_neg_32_pd, m68k_op_neg_32_pd, + m68k_op_neg_32_di, m68k_op_neg_32_di, m68k_op_neg_32_di, m68k_op_neg_32_di, m68k_op_neg_32_di, m68k_op_neg_32_di, m68k_op_neg_32_di, m68k_op_neg_32_di, + m68k_op_neg_32_ix, m68k_op_neg_32_ix, m68k_op_neg_32_ix, m68k_op_neg_32_ix, m68k_op_neg_32_ix, m68k_op_neg_32_ix, m68k_op_neg_32_ix, m68k_op_neg_32_ix, + m68k_op_neg_32_aw, m68k_op_neg_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_toc_d, m68k_op_move_16_toc_d, m68k_op_move_16_toc_d, m68k_op_move_16_toc_d, m68k_op_move_16_toc_d, m68k_op_move_16_toc_d, m68k_op_move_16_toc_d, m68k_op_move_16_toc_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_toc_ai, m68k_op_move_16_toc_ai, m68k_op_move_16_toc_ai, m68k_op_move_16_toc_ai, m68k_op_move_16_toc_ai, m68k_op_move_16_toc_ai, m68k_op_move_16_toc_ai, m68k_op_move_16_toc_ai, + m68k_op_move_16_toc_pi, m68k_op_move_16_toc_pi, m68k_op_move_16_toc_pi, m68k_op_move_16_toc_pi, m68k_op_move_16_toc_pi, m68k_op_move_16_toc_pi, m68k_op_move_16_toc_pi, m68k_op_move_16_toc_pi, + m68k_op_move_16_toc_pd, m68k_op_move_16_toc_pd, m68k_op_move_16_toc_pd, m68k_op_move_16_toc_pd, m68k_op_move_16_toc_pd, m68k_op_move_16_toc_pd, m68k_op_move_16_toc_pd, m68k_op_move_16_toc_pd, + m68k_op_move_16_toc_di, m68k_op_move_16_toc_di, m68k_op_move_16_toc_di, m68k_op_move_16_toc_di, m68k_op_move_16_toc_di, m68k_op_move_16_toc_di, m68k_op_move_16_toc_di, m68k_op_move_16_toc_di, + m68k_op_move_16_toc_ix, m68k_op_move_16_toc_ix, m68k_op_move_16_toc_ix, m68k_op_move_16_toc_ix, m68k_op_move_16_toc_ix, m68k_op_move_16_toc_ix, m68k_op_move_16_toc_ix, m68k_op_move_16_toc_ix, + m68k_op_move_16_toc_aw, m68k_op_move_16_toc_al, m68k_op_move_16_toc_pcdi, m68k_op_move_16_toc_pcix, m68k_op_move_16_toc_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, + m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, + m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, + m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, + m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, + m68k_op_chk_16_aw, m68k_op_chk_16_al, m68k_op_chk_16_pcdi, m68k_op_chk_16_pcix, m68k_op_chk_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, + m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, + m68k_op_lea_32_aw, m68k_op_lea_32_al, m68k_op_lea_32_pcdi, m68k_op_lea_32_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_not_8_d, m68k_op_not_8_d, m68k_op_not_8_d, m68k_op_not_8_d, m68k_op_not_8_d, m68k_op_not_8_d, m68k_op_not_8_d, m68k_op_not_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_not_8_ai, m68k_op_not_8_ai, m68k_op_not_8_ai, m68k_op_not_8_ai, m68k_op_not_8_ai, m68k_op_not_8_ai, m68k_op_not_8_ai, m68k_op_not_8_ai, + m68k_op_not_8_pi, m68k_op_not_8_pi, m68k_op_not_8_pi, m68k_op_not_8_pi, m68k_op_not_8_pi, m68k_op_not_8_pi, m68k_op_not_8_pi, m68k_op_not_8_pi7, + m68k_op_not_8_pd, m68k_op_not_8_pd, m68k_op_not_8_pd, m68k_op_not_8_pd, m68k_op_not_8_pd, m68k_op_not_8_pd, m68k_op_not_8_pd, m68k_op_not_8_pd7, + m68k_op_not_8_di, m68k_op_not_8_di, m68k_op_not_8_di, m68k_op_not_8_di, m68k_op_not_8_di, m68k_op_not_8_di, m68k_op_not_8_di, m68k_op_not_8_di, + m68k_op_not_8_ix, m68k_op_not_8_ix, m68k_op_not_8_ix, m68k_op_not_8_ix, m68k_op_not_8_ix, m68k_op_not_8_ix, m68k_op_not_8_ix, m68k_op_not_8_ix, + m68k_op_not_8_aw, m68k_op_not_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_not_16_d, m68k_op_not_16_d, m68k_op_not_16_d, m68k_op_not_16_d, m68k_op_not_16_d, m68k_op_not_16_d, m68k_op_not_16_d, m68k_op_not_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_not_16_ai, m68k_op_not_16_ai, m68k_op_not_16_ai, m68k_op_not_16_ai, m68k_op_not_16_ai, m68k_op_not_16_ai, m68k_op_not_16_ai, m68k_op_not_16_ai, + m68k_op_not_16_pi, m68k_op_not_16_pi, m68k_op_not_16_pi, m68k_op_not_16_pi, m68k_op_not_16_pi, m68k_op_not_16_pi, m68k_op_not_16_pi, m68k_op_not_16_pi, + m68k_op_not_16_pd, m68k_op_not_16_pd, m68k_op_not_16_pd, m68k_op_not_16_pd, m68k_op_not_16_pd, m68k_op_not_16_pd, m68k_op_not_16_pd, m68k_op_not_16_pd, + m68k_op_not_16_di, m68k_op_not_16_di, m68k_op_not_16_di, m68k_op_not_16_di, m68k_op_not_16_di, m68k_op_not_16_di, m68k_op_not_16_di, m68k_op_not_16_di, + m68k_op_not_16_ix, m68k_op_not_16_ix, m68k_op_not_16_ix, m68k_op_not_16_ix, m68k_op_not_16_ix, m68k_op_not_16_ix, m68k_op_not_16_ix, m68k_op_not_16_ix, + m68k_op_not_16_aw, m68k_op_not_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_not_32_d, m68k_op_not_32_d, m68k_op_not_32_d, m68k_op_not_32_d, m68k_op_not_32_d, m68k_op_not_32_d, m68k_op_not_32_d, m68k_op_not_32_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_not_32_ai, m68k_op_not_32_ai, m68k_op_not_32_ai, m68k_op_not_32_ai, m68k_op_not_32_ai, m68k_op_not_32_ai, m68k_op_not_32_ai, m68k_op_not_32_ai, + m68k_op_not_32_pi, m68k_op_not_32_pi, m68k_op_not_32_pi, m68k_op_not_32_pi, m68k_op_not_32_pi, m68k_op_not_32_pi, m68k_op_not_32_pi, m68k_op_not_32_pi, + m68k_op_not_32_pd, m68k_op_not_32_pd, m68k_op_not_32_pd, m68k_op_not_32_pd, m68k_op_not_32_pd, m68k_op_not_32_pd, m68k_op_not_32_pd, m68k_op_not_32_pd, + m68k_op_not_32_di, m68k_op_not_32_di, m68k_op_not_32_di, m68k_op_not_32_di, m68k_op_not_32_di, m68k_op_not_32_di, m68k_op_not_32_di, m68k_op_not_32_di, + m68k_op_not_32_ix, m68k_op_not_32_ix, m68k_op_not_32_ix, m68k_op_not_32_ix, m68k_op_not_32_ix, m68k_op_not_32_ix, m68k_op_not_32_ix, m68k_op_not_32_ix, + m68k_op_not_32_aw, m68k_op_not_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_tos_d, m68k_op_move_16_tos_d, m68k_op_move_16_tos_d, m68k_op_move_16_tos_d, m68k_op_move_16_tos_d, m68k_op_move_16_tos_d, m68k_op_move_16_tos_d, m68k_op_move_16_tos_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_move_16_tos_ai, m68k_op_move_16_tos_ai, m68k_op_move_16_tos_ai, m68k_op_move_16_tos_ai, m68k_op_move_16_tos_ai, m68k_op_move_16_tos_ai, m68k_op_move_16_tos_ai, m68k_op_move_16_tos_ai, + m68k_op_move_16_tos_pi, m68k_op_move_16_tos_pi, m68k_op_move_16_tos_pi, m68k_op_move_16_tos_pi, m68k_op_move_16_tos_pi, m68k_op_move_16_tos_pi, m68k_op_move_16_tos_pi, m68k_op_move_16_tos_pi, + m68k_op_move_16_tos_pd, m68k_op_move_16_tos_pd, m68k_op_move_16_tos_pd, m68k_op_move_16_tos_pd, m68k_op_move_16_tos_pd, m68k_op_move_16_tos_pd, m68k_op_move_16_tos_pd, m68k_op_move_16_tos_pd, + m68k_op_move_16_tos_di, m68k_op_move_16_tos_di, m68k_op_move_16_tos_di, m68k_op_move_16_tos_di, m68k_op_move_16_tos_di, m68k_op_move_16_tos_di, m68k_op_move_16_tos_di, m68k_op_move_16_tos_di, + m68k_op_move_16_tos_ix, m68k_op_move_16_tos_ix, m68k_op_move_16_tos_ix, m68k_op_move_16_tos_ix, m68k_op_move_16_tos_ix, m68k_op_move_16_tos_ix, m68k_op_move_16_tos_ix, m68k_op_move_16_tos_ix, + m68k_op_move_16_tos_aw, m68k_op_move_16_tos_al, m68k_op_move_16_tos_pcdi, m68k_op_move_16_tos_pcix, m68k_op_move_16_tos_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, + m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, + m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, + m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, + m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, + m68k_op_chk_16_aw, m68k_op_chk_16_al, m68k_op_chk_16_pcdi, m68k_op_chk_16_pcix, m68k_op_chk_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, + m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, + m68k_op_lea_32_aw, m68k_op_lea_32_al, m68k_op_lea_32_pcdi, m68k_op_lea_32_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_nbcd_8_d, m68k_op_nbcd_8_d, m68k_op_nbcd_8_d, m68k_op_nbcd_8_d, m68k_op_nbcd_8_d, m68k_op_nbcd_8_d, m68k_op_nbcd_8_d, m68k_op_nbcd_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_nbcd_8_ai, m68k_op_nbcd_8_ai, m68k_op_nbcd_8_ai, m68k_op_nbcd_8_ai, m68k_op_nbcd_8_ai, m68k_op_nbcd_8_ai, m68k_op_nbcd_8_ai, m68k_op_nbcd_8_ai, + m68k_op_nbcd_8_pi, m68k_op_nbcd_8_pi, m68k_op_nbcd_8_pi, m68k_op_nbcd_8_pi, m68k_op_nbcd_8_pi, m68k_op_nbcd_8_pi, m68k_op_nbcd_8_pi, m68k_op_nbcd_8_pi7, + m68k_op_nbcd_8_pd, m68k_op_nbcd_8_pd, m68k_op_nbcd_8_pd, m68k_op_nbcd_8_pd, m68k_op_nbcd_8_pd, m68k_op_nbcd_8_pd, m68k_op_nbcd_8_pd, m68k_op_nbcd_8_pd7, + m68k_op_nbcd_8_di, m68k_op_nbcd_8_di, m68k_op_nbcd_8_di, m68k_op_nbcd_8_di, m68k_op_nbcd_8_di, m68k_op_nbcd_8_di, m68k_op_nbcd_8_di, m68k_op_nbcd_8_di, + m68k_op_nbcd_8_ix, m68k_op_nbcd_8_ix, m68k_op_nbcd_8_ix, m68k_op_nbcd_8_ix, m68k_op_nbcd_8_ix, m68k_op_nbcd_8_ix, m68k_op_nbcd_8_ix, m68k_op_nbcd_8_ix, + m68k_op_nbcd_8_aw, m68k_op_nbcd_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_swap_32, m68k_op_swap_32, m68k_op_swap_32, m68k_op_swap_32, m68k_op_swap_32, m68k_op_swap_32, m68k_op_swap_32, m68k_op_swap_32, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_pea_32_ai, m68k_op_pea_32_ai, m68k_op_pea_32_ai, m68k_op_pea_32_ai, m68k_op_pea_32_ai, m68k_op_pea_32_ai, m68k_op_pea_32_ai, m68k_op_pea_32_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_pea_32_di, m68k_op_pea_32_di, m68k_op_pea_32_di, m68k_op_pea_32_di, m68k_op_pea_32_di, m68k_op_pea_32_di, m68k_op_pea_32_di, m68k_op_pea_32_di, + m68k_op_pea_32_ix, m68k_op_pea_32_ix, m68k_op_pea_32_ix, m68k_op_pea_32_ix, m68k_op_pea_32_ix, m68k_op_pea_32_ix, m68k_op_pea_32_ix, m68k_op_pea_32_ix, + m68k_op_pea_32_aw, m68k_op_pea_32_al, m68k_op_pea_32_pcdi, m68k_op_pea_32_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_ext_16, m68k_op_ext_16, m68k_op_ext_16, m68k_op_ext_16, m68k_op_ext_16, m68k_op_ext_16, m68k_op_ext_16, m68k_op_ext_16, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movem_16_re_ai, m68k_op_movem_16_re_ai, m68k_op_movem_16_re_ai, m68k_op_movem_16_re_ai, m68k_op_movem_16_re_ai, m68k_op_movem_16_re_ai, m68k_op_movem_16_re_ai, m68k_op_movem_16_re_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movem_16_re_pd, m68k_op_movem_16_re_pd, m68k_op_movem_16_re_pd, m68k_op_movem_16_re_pd, m68k_op_movem_16_re_pd, m68k_op_movem_16_re_pd, m68k_op_movem_16_re_pd, m68k_op_movem_16_re_pd, + m68k_op_movem_16_re_di, m68k_op_movem_16_re_di, m68k_op_movem_16_re_di, m68k_op_movem_16_re_di, m68k_op_movem_16_re_di, m68k_op_movem_16_re_di, m68k_op_movem_16_re_di, m68k_op_movem_16_re_di, + m68k_op_movem_16_re_ix, m68k_op_movem_16_re_ix, m68k_op_movem_16_re_ix, m68k_op_movem_16_re_ix, m68k_op_movem_16_re_ix, m68k_op_movem_16_re_ix, m68k_op_movem_16_re_ix, m68k_op_movem_16_re_ix, + m68k_op_movem_16_re_aw, m68k_op_movem_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_ext_32, m68k_op_ext_32, m68k_op_ext_32, m68k_op_ext_32, m68k_op_ext_32, m68k_op_ext_32, m68k_op_ext_32, m68k_op_ext_32, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movem_32_re_ai, m68k_op_movem_32_re_ai, m68k_op_movem_32_re_ai, m68k_op_movem_32_re_ai, m68k_op_movem_32_re_ai, m68k_op_movem_32_re_ai, m68k_op_movem_32_re_ai, m68k_op_movem_32_re_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movem_32_re_pd, m68k_op_movem_32_re_pd, m68k_op_movem_32_re_pd, m68k_op_movem_32_re_pd, m68k_op_movem_32_re_pd, m68k_op_movem_32_re_pd, m68k_op_movem_32_re_pd, m68k_op_movem_32_re_pd, + m68k_op_movem_32_re_di, m68k_op_movem_32_re_di, m68k_op_movem_32_re_di, m68k_op_movem_32_re_di, m68k_op_movem_32_re_di, m68k_op_movem_32_re_di, m68k_op_movem_32_re_di, m68k_op_movem_32_re_di, + m68k_op_movem_32_re_ix, m68k_op_movem_32_re_ix, m68k_op_movem_32_re_ix, m68k_op_movem_32_re_ix, m68k_op_movem_32_re_ix, m68k_op_movem_32_re_ix, m68k_op_movem_32_re_ix, m68k_op_movem_32_re_ix, + m68k_op_movem_32_re_aw, m68k_op_movem_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, + m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, + m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, + m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, + m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, + m68k_op_chk_16_aw, m68k_op_chk_16_al, m68k_op_chk_16_pcdi, m68k_op_chk_16_pcix, m68k_op_chk_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, + m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, + m68k_op_lea_32_aw, m68k_op_lea_32_al, m68k_op_lea_32_pcdi, m68k_op_lea_32_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_tst_8_d, m68k_op_tst_8_d, m68k_op_tst_8_d, m68k_op_tst_8_d, m68k_op_tst_8_d, m68k_op_tst_8_d, m68k_op_tst_8_d, m68k_op_tst_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_tst_8_ai, m68k_op_tst_8_ai, m68k_op_tst_8_ai, m68k_op_tst_8_ai, m68k_op_tst_8_ai, m68k_op_tst_8_ai, m68k_op_tst_8_ai, m68k_op_tst_8_ai, + m68k_op_tst_8_pi, m68k_op_tst_8_pi, m68k_op_tst_8_pi, m68k_op_tst_8_pi, m68k_op_tst_8_pi, m68k_op_tst_8_pi, m68k_op_tst_8_pi, m68k_op_tst_8_pi7, + m68k_op_tst_8_pd, m68k_op_tst_8_pd, m68k_op_tst_8_pd, m68k_op_tst_8_pd, m68k_op_tst_8_pd, m68k_op_tst_8_pd, m68k_op_tst_8_pd, m68k_op_tst_8_pd7, + m68k_op_tst_8_di, m68k_op_tst_8_di, m68k_op_tst_8_di, m68k_op_tst_8_di, m68k_op_tst_8_di, m68k_op_tst_8_di, m68k_op_tst_8_di, m68k_op_tst_8_di, + m68k_op_tst_8_ix, m68k_op_tst_8_ix, m68k_op_tst_8_ix, m68k_op_tst_8_ix, m68k_op_tst_8_ix, m68k_op_tst_8_ix, m68k_op_tst_8_ix, m68k_op_tst_8_ix, + m68k_op_tst_8_aw, m68k_op_tst_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_tst_16_d, m68k_op_tst_16_d, m68k_op_tst_16_d, m68k_op_tst_16_d, m68k_op_tst_16_d, m68k_op_tst_16_d, m68k_op_tst_16_d, m68k_op_tst_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_tst_16_ai, m68k_op_tst_16_ai, m68k_op_tst_16_ai, m68k_op_tst_16_ai, m68k_op_tst_16_ai, m68k_op_tst_16_ai, m68k_op_tst_16_ai, m68k_op_tst_16_ai, + m68k_op_tst_16_pi, m68k_op_tst_16_pi, m68k_op_tst_16_pi, m68k_op_tst_16_pi, m68k_op_tst_16_pi, m68k_op_tst_16_pi, m68k_op_tst_16_pi, m68k_op_tst_16_pi, + m68k_op_tst_16_pd, m68k_op_tst_16_pd, m68k_op_tst_16_pd, m68k_op_tst_16_pd, m68k_op_tst_16_pd, m68k_op_tst_16_pd, m68k_op_tst_16_pd, m68k_op_tst_16_pd, + m68k_op_tst_16_di, m68k_op_tst_16_di, m68k_op_tst_16_di, m68k_op_tst_16_di, m68k_op_tst_16_di, m68k_op_tst_16_di, m68k_op_tst_16_di, m68k_op_tst_16_di, + m68k_op_tst_16_ix, m68k_op_tst_16_ix, m68k_op_tst_16_ix, m68k_op_tst_16_ix, m68k_op_tst_16_ix, m68k_op_tst_16_ix, m68k_op_tst_16_ix, m68k_op_tst_16_ix, + m68k_op_tst_16_aw, m68k_op_tst_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_tst_32_d, m68k_op_tst_32_d, m68k_op_tst_32_d, m68k_op_tst_32_d, m68k_op_tst_32_d, m68k_op_tst_32_d, m68k_op_tst_32_d, m68k_op_tst_32_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_tst_32_ai, m68k_op_tst_32_ai, m68k_op_tst_32_ai, m68k_op_tst_32_ai, m68k_op_tst_32_ai, m68k_op_tst_32_ai, m68k_op_tst_32_ai, m68k_op_tst_32_ai, + m68k_op_tst_32_pi, m68k_op_tst_32_pi, m68k_op_tst_32_pi, m68k_op_tst_32_pi, m68k_op_tst_32_pi, m68k_op_tst_32_pi, m68k_op_tst_32_pi, m68k_op_tst_32_pi, + m68k_op_tst_32_pd, m68k_op_tst_32_pd, m68k_op_tst_32_pd, m68k_op_tst_32_pd, m68k_op_tst_32_pd, m68k_op_tst_32_pd, m68k_op_tst_32_pd, m68k_op_tst_32_pd, + m68k_op_tst_32_di, m68k_op_tst_32_di, m68k_op_tst_32_di, m68k_op_tst_32_di, m68k_op_tst_32_di, m68k_op_tst_32_di, m68k_op_tst_32_di, m68k_op_tst_32_di, + m68k_op_tst_32_ix, m68k_op_tst_32_ix, m68k_op_tst_32_ix, m68k_op_tst_32_ix, m68k_op_tst_32_ix, m68k_op_tst_32_ix, m68k_op_tst_32_ix, m68k_op_tst_32_ix, + m68k_op_tst_32_aw, m68k_op_tst_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_tas_8_d, m68k_op_tas_8_d, m68k_op_tas_8_d, m68k_op_tas_8_d, m68k_op_tas_8_d, m68k_op_tas_8_d, m68k_op_tas_8_d, m68k_op_tas_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_tas_8_ai, m68k_op_tas_8_ai, m68k_op_tas_8_ai, m68k_op_tas_8_ai, m68k_op_tas_8_ai, m68k_op_tas_8_ai, m68k_op_tas_8_ai, m68k_op_tas_8_ai, + m68k_op_tas_8_pi, m68k_op_tas_8_pi, m68k_op_tas_8_pi, m68k_op_tas_8_pi, m68k_op_tas_8_pi, m68k_op_tas_8_pi, m68k_op_tas_8_pi, m68k_op_tas_8_pi7, + m68k_op_tas_8_pd, m68k_op_tas_8_pd, m68k_op_tas_8_pd, m68k_op_tas_8_pd, m68k_op_tas_8_pd, m68k_op_tas_8_pd, m68k_op_tas_8_pd, m68k_op_tas_8_pd7, + m68k_op_tas_8_di, m68k_op_tas_8_di, m68k_op_tas_8_di, m68k_op_tas_8_di, m68k_op_tas_8_di, m68k_op_tas_8_di, m68k_op_tas_8_di, m68k_op_tas_8_di, + m68k_op_tas_8_ix, m68k_op_tas_8_ix, m68k_op_tas_8_ix, m68k_op_tas_8_ix, m68k_op_tas_8_ix, m68k_op_tas_8_ix, m68k_op_tas_8_ix, m68k_op_tas_8_ix, + m68k_op_tas_8_aw, m68k_op_tas_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, + m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, + m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, + m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, + m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, + m68k_op_chk_16_aw, m68k_op_chk_16_al, m68k_op_chk_16_pcdi, m68k_op_chk_16_pcix, m68k_op_chk_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, + m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, + m68k_op_lea_32_aw, m68k_op_lea_32_al, m68k_op_lea_32_pcdi, m68k_op_lea_32_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movem_16_er_ai, m68k_op_movem_16_er_ai, m68k_op_movem_16_er_ai, m68k_op_movem_16_er_ai, m68k_op_movem_16_er_ai, m68k_op_movem_16_er_ai, m68k_op_movem_16_er_ai, m68k_op_movem_16_er_ai, + m68k_op_movem_16_er_pi, m68k_op_movem_16_er_pi, m68k_op_movem_16_er_pi, m68k_op_movem_16_er_pi, m68k_op_movem_16_er_pi, m68k_op_movem_16_er_pi, m68k_op_movem_16_er_pi, m68k_op_movem_16_er_pi, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movem_16_er_di, m68k_op_movem_16_er_di, m68k_op_movem_16_er_di, m68k_op_movem_16_er_di, m68k_op_movem_16_er_di, m68k_op_movem_16_er_di, m68k_op_movem_16_er_di, m68k_op_movem_16_er_di, + m68k_op_movem_16_er_ix, m68k_op_movem_16_er_ix, m68k_op_movem_16_er_ix, m68k_op_movem_16_er_ix, m68k_op_movem_16_er_ix, m68k_op_movem_16_er_ix, m68k_op_movem_16_er_ix, m68k_op_movem_16_er_ix, + m68k_op_movem_16_er_aw, m68k_op_movem_16_er_al, m68k_op_movem_16_er_pcdi, m68k_op_movem_16_er_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movem_32_er_ai, m68k_op_movem_32_er_ai, m68k_op_movem_32_er_ai, m68k_op_movem_32_er_ai, m68k_op_movem_32_er_ai, m68k_op_movem_32_er_ai, m68k_op_movem_32_er_ai, m68k_op_movem_32_er_ai, + m68k_op_movem_32_er_pi, m68k_op_movem_32_er_pi, m68k_op_movem_32_er_pi, m68k_op_movem_32_er_pi, m68k_op_movem_32_er_pi, m68k_op_movem_32_er_pi, m68k_op_movem_32_er_pi, m68k_op_movem_32_er_pi, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_movem_32_er_di, m68k_op_movem_32_er_di, m68k_op_movem_32_er_di, m68k_op_movem_32_er_di, m68k_op_movem_32_er_di, m68k_op_movem_32_er_di, m68k_op_movem_32_er_di, m68k_op_movem_32_er_di, + m68k_op_movem_32_er_ix, m68k_op_movem_32_er_ix, m68k_op_movem_32_er_ix, m68k_op_movem_32_er_ix, m68k_op_movem_32_er_ix, m68k_op_movem_32_er_ix, m68k_op_movem_32_er_ix, m68k_op_movem_32_er_ix, + m68k_op_movem_32_er_aw, m68k_op_movem_32_er_al, m68k_op_movem_32_er_pcdi, m68k_op_movem_32_er_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, + m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, + m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, + m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, + m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, + m68k_op_chk_16_aw, m68k_op_chk_16_al, m68k_op_chk_16_pcdi, m68k_op_chk_16_pcix, m68k_op_chk_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, + m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, + m68k_op_lea_32_aw, m68k_op_lea_32_al, m68k_op_lea_32_pcdi, m68k_op_lea_32_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_trap, m68k_op_trap, m68k_op_trap, m68k_op_trap, m68k_op_trap, m68k_op_trap, m68k_op_trap, m68k_op_trap, + m68k_op_trap, m68k_op_trap, m68k_op_trap, m68k_op_trap, m68k_op_trap, m68k_op_trap, m68k_op_trap, m68k_op_trap, + m68k_op_link_16, m68k_op_link_16, m68k_op_link_16, m68k_op_link_16, m68k_op_link_16, m68k_op_link_16, m68k_op_link_16, m68k_op_link_16_a7, + m68k_op_unlk_32, m68k_op_unlk_32, m68k_op_unlk_32, m68k_op_unlk_32, m68k_op_unlk_32, m68k_op_unlk_32, m68k_op_unlk_32, m68k_op_unlk_32_a7, + m68k_op_move_32_tou, m68k_op_move_32_tou, m68k_op_move_32_tou, m68k_op_move_32_tou, m68k_op_move_32_tou, m68k_op_move_32_tou, m68k_op_move_32_tou, m68k_op_move_32_tou, + m68k_op_move_32_fru, m68k_op_move_32_fru, m68k_op_move_32_fru, m68k_op_move_32_fru, m68k_op_move_32_fru, m68k_op_move_32_fru, m68k_op_move_32_fru, m68k_op_move_32_fru, + m68k_op_reset, m68k_op_nop, m68k_op_stop, m68k_op_rte_32, m68k_op_illegal, m68k_op_rts_32, m68k_op_trapv, m68k_op_rtr_32, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_jsr_32_ai, m68k_op_jsr_32_ai, m68k_op_jsr_32_ai, m68k_op_jsr_32_ai, m68k_op_jsr_32_ai, m68k_op_jsr_32_ai, m68k_op_jsr_32_ai, m68k_op_jsr_32_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_jsr_32_di, m68k_op_jsr_32_di, m68k_op_jsr_32_di, m68k_op_jsr_32_di, m68k_op_jsr_32_di, m68k_op_jsr_32_di, m68k_op_jsr_32_di, m68k_op_jsr_32_di, + m68k_op_jsr_32_ix, m68k_op_jsr_32_ix, m68k_op_jsr_32_ix, m68k_op_jsr_32_ix, m68k_op_jsr_32_ix, m68k_op_jsr_32_ix, m68k_op_jsr_32_ix, m68k_op_jsr_32_ix, + m68k_op_jsr_32_aw, m68k_op_jsr_32_al, m68k_op_jsr_32_pcdi, m68k_op_jsr_32_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_jmp_32_ai, m68k_op_jmp_32_ai, m68k_op_jmp_32_ai, m68k_op_jmp_32_ai, m68k_op_jmp_32_ai, m68k_op_jmp_32_ai, m68k_op_jmp_32_ai, m68k_op_jmp_32_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_jmp_32_di, m68k_op_jmp_32_di, m68k_op_jmp_32_di, m68k_op_jmp_32_di, m68k_op_jmp_32_di, m68k_op_jmp_32_di, m68k_op_jmp_32_di, m68k_op_jmp_32_di, + m68k_op_jmp_32_ix, m68k_op_jmp_32_ix, m68k_op_jmp_32_ix, m68k_op_jmp_32_ix, m68k_op_jmp_32_ix, m68k_op_jmp_32_ix, m68k_op_jmp_32_ix, m68k_op_jmp_32_ix, + m68k_op_jmp_32_aw, m68k_op_jmp_32_al, m68k_op_jmp_32_pcdi, m68k_op_jmp_32_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, m68k_op_chk_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, m68k_op_chk_16_ai, + m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, m68k_op_chk_16_pi, + m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, m68k_op_chk_16_pd, + m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, m68k_op_chk_16_di, + m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, m68k_op_chk_16_ix, + m68k_op_chk_16_aw, m68k_op_chk_16_al, m68k_op_chk_16_pcdi, m68k_op_chk_16_pcix, m68k_op_chk_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, m68k_op_lea_32_ai, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, m68k_op_lea_32_di, + m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, m68k_op_lea_32_ix, + m68k_op_lea_32_aw, m68k_op_lea_32_al, m68k_op_lea_32_pcdi, m68k_op_lea_32_pcix, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, + m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi7, + m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd7, + m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, + m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, + m68k_op_addq_8_aw, m68k_op_addq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, + m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, + m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, + m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, + m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, + m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, + m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, + m68k_op_addq_16_aw, m68k_op_addq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, + m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, + m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, + m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, + m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, + m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, + m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, + m68k_op_addq_32_aw, m68k_op_addq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_st_8_d, m68k_op_st_8_d, m68k_op_st_8_d, m68k_op_st_8_d, m68k_op_st_8_d, m68k_op_st_8_d, m68k_op_st_8_d, m68k_op_st_8_d, + m68k_op_dbt_16, m68k_op_dbt_16, m68k_op_dbt_16, m68k_op_dbt_16, m68k_op_dbt_16, m68k_op_dbt_16, m68k_op_dbt_16, m68k_op_dbt_16, + m68k_op_st_8_ai, m68k_op_st_8_ai, m68k_op_st_8_ai, m68k_op_st_8_ai, m68k_op_st_8_ai, m68k_op_st_8_ai, m68k_op_st_8_ai, m68k_op_st_8_ai, + m68k_op_st_8_pi, m68k_op_st_8_pi, m68k_op_st_8_pi, m68k_op_st_8_pi, m68k_op_st_8_pi, m68k_op_st_8_pi, m68k_op_st_8_pi, m68k_op_st_8_pi7, + m68k_op_st_8_pd, m68k_op_st_8_pd, m68k_op_st_8_pd, m68k_op_st_8_pd, m68k_op_st_8_pd, m68k_op_st_8_pd, m68k_op_st_8_pd, m68k_op_st_8_pd7, + m68k_op_st_8_di, m68k_op_st_8_di, m68k_op_st_8_di, m68k_op_st_8_di, m68k_op_st_8_di, m68k_op_st_8_di, m68k_op_st_8_di, m68k_op_st_8_di, + m68k_op_st_8_ix, m68k_op_st_8_ix, m68k_op_st_8_ix, m68k_op_st_8_ix, m68k_op_st_8_ix, m68k_op_st_8_ix, m68k_op_st_8_ix, m68k_op_st_8_ix, + m68k_op_st_8_aw, m68k_op_st_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, + m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi7, + m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd7, + m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, + m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, + m68k_op_subq_8_aw, m68k_op_subq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, + m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, + m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, + m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, + m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, + m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, + m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, + m68k_op_subq_16_aw, m68k_op_subq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, + m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, + m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, + m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, + m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, + m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, + m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, + m68k_op_subq_32_aw, m68k_op_subq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sf_8_d, m68k_op_sf_8_d, m68k_op_sf_8_d, m68k_op_sf_8_d, m68k_op_sf_8_d, m68k_op_sf_8_d, m68k_op_sf_8_d, m68k_op_sf_8_d, + m68k_op_dbf_16, m68k_op_dbf_16, m68k_op_dbf_16, m68k_op_dbf_16, m68k_op_dbf_16, m68k_op_dbf_16, m68k_op_dbf_16, m68k_op_dbf_16, + m68k_op_sf_8_ai, m68k_op_sf_8_ai, m68k_op_sf_8_ai, m68k_op_sf_8_ai, m68k_op_sf_8_ai, m68k_op_sf_8_ai, m68k_op_sf_8_ai, m68k_op_sf_8_ai, + m68k_op_sf_8_pi, m68k_op_sf_8_pi, m68k_op_sf_8_pi, m68k_op_sf_8_pi, m68k_op_sf_8_pi, m68k_op_sf_8_pi, m68k_op_sf_8_pi, m68k_op_sf_8_pi7, + m68k_op_sf_8_pd, m68k_op_sf_8_pd, m68k_op_sf_8_pd, m68k_op_sf_8_pd, m68k_op_sf_8_pd, m68k_op_sf_8_pd, m68k_op_sf_8_pd, m68k_op_sf_8_pd7, + m68k_op_sf_8_di, m68k_op_sf_8_di, m68k_op_sf_8_di, m68k_op_sf_8_di, m68k_op_sf_8_di, m68k_op_sf_8_di, m68k_op_sf_8_di, m68k_op_sf_8_di, + m68k_op_sf_8_ix, m68k_op_sf_8_ix, m68k_op_sf_8_ix, m68k_op_sf_8_ix, m68k_op_sf_8_ix, m68k_op_sf_8_ix, m68k_op_sf_8_ix, m68k_op_sf_8_ix, + m68k_op_sf_8_aw, m68k_op_sf_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, + m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi7, + m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd7, + m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, + m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, + m68k_op_addq_8_aw, m68k_op_addq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, + m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, + m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, + m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, + m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, + m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, + m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, + m68k_op_addq_16_aw, m68k_op_addq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, + m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, + m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, + m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, + m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, + m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, + m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, + m68k_op_addq_32_aw, m68k_op_addq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_shi_8_d, m68k_op_shi_8_d, m68k_op_shi_8_d, m68k_op_shi_8_d, m68k_op_shi_8_d, m68k_op_shi_8_d, m68k_op_shi_8_d, m68k_op_shi_8_d, + m68k_op_dbhi_16, m68k_op_dbhi_16, m68k_op_dbhi_16, m68k_op_dbhi_16, m68k_op_dbhi_16, m68k_op_dbhi_16, m68k_op_dbhi_16, m68k_op_dbhi_16, + m68k_op_shi_8_ai, m68k_op_shi_8_ai, m68k_op_shi_8_ai, m68k_op_shi_8_ai, m68k_op_shi_8_ai, m68k_op_shi_8_ai, m68k_op_shi_8_ai, m68k_op_shi_8_ai, + m68k_op_shi_8_pi, m68k_op_shi_8_pi, m68k_op_shi_8_pi, m68k_op_shi_8_pi, m68k_op_shi_8_pi, m68k_op_shi_8_pi, m68k_op_shi_8_pi, m68k_op_shi_8_pi7, + m68k_op_shi_8_pd, m68k_op_shi_8_pd, m68k_op_shi_8_pd, m68k_op_shi_8_pd, m68k_op_shi_8_pd, m68k_op_shi_8_pd, m68k_op_shi_8_pd, m68k_op_shi_8_pd7, + m68k_op_shi_8_di, m68k_op_shi_8_di, m68k_op_shi_8_di, m68k_op_shi_8_di, m68k_op_shi_8_di, m68k_op_shi_8_di, m68k_op_shi_8_di, m68k_op_shi_8_di, + m68k_op_shi_8_ix, m68k_op_shi_8_ix, m68k_op_shi_8_ix, m68k_op_shi_8_ix, m68k_op_shi_8_ix, m68k_op_shi_8_ix, m68k_op_shi_8_ix, m68k_op_shi_8_ix, + m68k_op_shi_8_aw, m68k_op_shi_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, + m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi7, + m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd7, + m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, + m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, + m68k_op_subq_8_aw, m68k_op_subq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, + m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, + m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, + m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, + m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, + m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, + m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, + m68k_op_subq_16_aw, m68k_op_subq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, + m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, + m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, + m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, + m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, + m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, + m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, + m68k_op_subq_32_aw, m68k_op_subq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sls_8_d, m68k_op_sls_8_d, m68k_op_sls_8_d, m68k_op_sls_8_d, m68k_op_sls_8_d, m68k_op_sls_8_d, m68k_op_sls_8_d, m68k_op_sls_8_d, + m68k_op_dbls_16, m68k_op_dbls_16, m68k_op_dbls_16, m68k_op_dbls_16, m68k_op_dbls_16, m68k_op_dbls_16, m68k_op_dbls_16, m68k_op_dbls_16, + m68k_op_sls_8_ai, m68k_op_sls_8_ai, m68k_op_sls_8_ai, m68k_op_sls_8_ai, m68k_op_sls_8_ai, m68k_op_sls_8_ai, m68k_op_sls_8_ai, m68k_op_sls_8_ai, + m68k_op_sls_8_pi, m68k_op_sls_8_pi, m68k_op_sls_8_pi, m68k_op_sls_8_pi, m68k_op_sls_8_pi, m68k_op_sls_8_pi, m68k_op_sls_8_pi, m68k_op_sls_8_pi7, + m68k_op_sls_8_pd, m68k_op_sls_8_pd, m68k_op_sls_8_pd, m68k_op_sls_8_pd, m68k_op_sls_8_pd, m68k_op_sls_8_pd, m68k_op_sls_8_pd, m68k_op_sls_8_pd7, + m68k_op_sls_8_di, m68k_op_sls_8_di, m68k_op_sls_8_di, m68k_op_sls_8_di, m68k_op_sls_8_di, m68k_op_sls_8_di, m68k_op_sls_8_di, m68k_op_sls_8_di, + m68k_op_sls_8_ix, m68k_op_sls_8_ix, m68k_op_sls_8_ix, m68k_op_sls_8_ix, m68k_op_sls_8_ix, m68k_op_sls_8_ix, m68k_op_sls_8_ix, m68k_op_sls_8_ix, + m68k_op_sls_8_aw, m68k_op_sls_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, + m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi7, + m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd7, + m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, + m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, + m68k_op_addq_8_aw, m68k_op_addq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, + m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, + m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, + m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, + m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, + m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, + m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, + m68k_op_addq_16_aw, m68k_op_addq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, + m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, + m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, + m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, + m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, + m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, + m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, + m68k_op_addq_32_aw, m68k_op_addq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_scc_8_d, m68k_op_scc_8_d, m68k_op_scc_8_d, m68k_op_scc_8_d, m68k_op_scc_8_d, m68k_op_scc_8_d, m68k_op_scc_8_d, m68k_op_scc_8_d, + m68k_op_dbcc_16, m68k_op_dbcc_16, m68k_op_dbcc_16, m68k_op_dbcc_16, m68k_op_dbcc_16, m68k_op_dbcc_16, m68k_op_dbcc_16, m68k_op_dbcc_16, + m68k_op_scc_8_ai, m68k_op_scc_8_ai, m68k_op_scc_8_ai, m68k_op_scc_8_ai, m68k_op_scc_8_ai, m68k_op_scc_8_ai, m68k_op_scc_8_ai, m68k_op_scc_8_ai, + m68k_op_scc_8_pi, m68k_op_scc_8_pi, m68k_op_scc_8_pi, m68k_op_scc_8_pi, m68k_op_scc_8_pi, m68k_op_scc_8_pi, m68k_op_scc_8_pi, m68k_op_scc_8_pi7, + m68k_op_scc_8_pd, m68k_op_scc_8_pd, m68k_op_scc_8_pd, m68k_op_scc_8_pd, m68k_op_scc_8_pd, m68k_op_scc_8_pd, m68k_op_scc_8_pd, m68k_op_scc_8_pd7, + m68k_op_scc_8_di, m68k_op_scc_8_di, m68k_op_scc_8_di, m68k_op_scc_8_di, m68k_op_scc_8_di, m68k_op_scc_8_di, m68k_op_scc_8_di, m68k_op_scc_8_di, + m68k_op_scc_8_ix, m68k_op_scc_8_ix, m68k_op_scc_8_ix, m68k_op_scc_8_ix, m68k_op_scc_8_ix, m68k_op_scc_8_ix, m68k_op_scc_8_ix, m68k_op_scc_8_ix, + m68k_op_scc_8_aw, m68k_op_scc_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, + m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi7, + m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd7, + m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, + m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, + m68k_op_subq_8_aw, m68k_op_subq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, + m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, + m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, + m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, + m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, + m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, + m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, + m68k_op_subq_16_aw, m68k_op_subq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, + m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, + m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, + m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, + m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, + m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, + m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, + m68k_op_subq_32_aw, m68k_op_subq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_scs_8_d, m68k_op_scs_8_d, m68k_op_scs_8_d, m68k_op_scs_8_d, m68k_op_scs_8_d, m68k_op_scs_8_d, m68k_op_scs_8_d, m68k_op_scs_8_d, + m68k_op_dbcs_16, m68k_op_dbcs_16, m68k_op_dbcs_16, m68k_op_dbcs_16, m68k_op_dbcs_16, m68k_op_dbcs_16, m68k_op_dbcs_16, m68k_op_dbcs_16, + m68k_op_scs_8_ai, m68k_op_scs_8_ai, m68k_op_scs_8_ai, m68k_op_scs_8_ai, m68k_op_scs_8_ai, m68k_op_scs_8_ai, m68k_op_scs_8_ai, m68k_op_scs_8_ai, + m68k_op_scs_8_pi, m68k_op_scs_8_pi, m68k_op_scs_8_pi, m68k_op_scs_8_pi, m68k_op_scs_8_pi, m68k_op_scs_8_pi, m68k_op_scs_8_pi, m68k_op_scs_8_pi7, + m68k_op_scs_8_pd, m68k_op_scs_8_pd, m68k_op_scs_8_pd, m68k_op_scs_8_pd, m68k_op_scs_8_pd, m68k_op_scs_8_pd, m68k_op_scs_8_pd, m68k_op_scs_8_pd7, + m68k_op_scs_8_di, m68k_op_scs_8_di, m68k_op_scs_8_di, m68k_op_scs_8_di, m68k_op_scs_8_di, m68k_op_scs_8_di, m68k_op_scs_8_di, m68k_op_scs_8_di, + m68k_op_scs_8_ix, m68k_op_scs_8_ix, m68k_op_scs_8_ix, m68k_op_scs_8_ix, m68k_op_scs_8_ix, m68k_op_scs_8_ix, m68k_op_scs_8_ix, m68k_op_scs_8_ix, + m68k_op_scs_8_aw, m68k_op_scs_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, + m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi7, + m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd7, + m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, + m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, + m68k_op_addq_8_aw, m68k_op_addq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, + m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, + m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, + m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, + m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, + m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, + m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, + m68k_op_addq_16_aw, m68k_op_addq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, + m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, + m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, + m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, + m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, + m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, + m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, + m68k_op_addq_32_aw, m68k_op_addq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sne_8_d, m68k_op_sne_8_d, m68k_op_sne_8_d, m68k_op_sne_8_d, m68k_op_sne_8_d, m68k_op_sne_8_d, m68k_op_sne_8_d, m68k_op_sne_8_d, + m68k_op_dbne_16, m68k_op_dbne_16, m68k_op_dbne_16, m68k_op_dbne_16, m68k_op_dbne_16, m68k_op_dbne_16, m68k_op_dbne_16, m68k_op_dbne_16, + m68k_op_sne_8_ai, m68k_op_sne_8_ai, m68k_op_sne_8_ai, m68k_op_sne_8_ai, m68k_op_sne_8_ai, m68k_op_sne_8_ai, m68k_op_sne_8_ai, m68k_op_sne_8_ai, + m68k_op_sne_8_pi, m68k_op_sne_8_pi, m68k_op_sne_8_pi, m68k_op_sne_8_pi, m68k_op_sne_8_pi, m68k_op_sne_8_pi, m68k_op_sne_8_pi, m68k_op_sne_8_pi7, + m68k_op_sne_8_pd, m68k_op_sne_8_pd, m68k_op_sne_8_pd, m68k_op_sne_8_pd, m68k_op_sne_8_pd, m68k_op_sne_8_pd, m68k_op_sne_8_pd, m68k_op_sne_8_pd7, + m68k_op_sne_8_di, m68k_op_sne_8_di, m68k_op_sne_8_di, m68k_op_sne_8_di, m68k_op_sne_8_di, m68k_op_sne_8_di, m68k_op_sne_8_di, m68k_op_sne_8_di, + m68k_op_sne_8_ix, m68k_op_sne_8_ix, m68k_op_sne_8_ix, m68k_op_sne_8_ix, m68k_op_sne_8_ix, m68k_op_sne_8_ix, m68k_op_sne_8_ix, m68k_op_sne_8_ix, + m68k_op_sne_8_aw, m68k_op_sne_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, + m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi7, + m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd7, + m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, + m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, + m68k_op_subq_8_aw, m68k_op_subq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, + m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, + m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, + m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, + m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, + m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, + m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, + m68k_op_subq_16_aw, m68k_op_subq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, + m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, + m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, + m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, + m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, + m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, + m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, + m68k_op_subq_32_aw, m68k_op_subq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_seq_8_d, m68k_op_seq_8_d, m68k_op_seq_8_d, m68k_op_seq_8_d, m68k_op_seq_8_d, m68k_op_seq_8_d, m68k_op_seq_8_d, m68k_op_seq_8_d, + m68k_op_dbeq_16, m68k_op_dbeq_16, m68k_op_dbeq_16, m68k_op_dbeq_16, m68k_op_dbeq_16, m68k_op_dbeq_16, m68k_op_dbeq_16, m68k_op_dbeq_16, + m68k_op_seq_8_ai, m68k_op_seq_8_ai, m68k_op_seq_8_ai, m68k_op_seq_8_ai, m68k_op_seq_8_ai, m68k_op_seq_8_ai, m68k_op_seq_8_ai, m68k_op_seq_8_ai, + m68k_op_seq_8_pi, m68k_op_seq_8_pi, m68k_op_seq_8_pi, m68k_op_seq_8_pi, m68k_op_seq_8_pi, m68k_op_seq_8_pi, m68k_op_seq_8_pi, m68k_op_seq_8_pi7, + m68k_op_seq_8_pd, m68k_op_seq_8_pd, m68k_op_seq_8_pd, m68k_op_seq_8_pd, m68k_op_seq_8_pd, m68k_op_seq_8_pd, m68k_op_seq_8_pd, m68k_op_seq_8_pd7, + m68k_op_seq_8_di, m68k_op_seq_8_di, m68k_op_seq_8_di, m68k_op_seq_8_di, m68k_op_seq_8_di, m68k_op_seq_8_di, m68k_op_seq_8_di, m68k_op_seq_8_di, + m68k_op_seq_8_ix, m68k_op_seq_8_ix, m68k_op_seq_8_ix, m68k_op_seq_8_ix, m68k_op_seq_8_ix, m68k_op_seq_8_ix, m68k_op_seq_8_ix, m68k_op_seq_8_ix, + m68k_op_seq_8_aw, m68k_op_seq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, + m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi7, + m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd7, + m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, + m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, + m68k_op_addq_8_aw, m68k_op_addq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, + m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, + m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, + m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, + m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, + m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, + m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, + m68k_op_addq_16_aw, m68k_op_addq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, + m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, + m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, + m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, + m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, + m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, + m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, + m68k_op_addq_32_aw, m68k_op_addq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_svc_8_d, m68k_op_svc_8_d, m68k_op_svc_8_d, m68k_op_svc_8_d, m68k_op_svc_8_d, m68k_op_svc_8_d, m68k_op_svc_8_d, m68k_op_svc_8_d, + m68k_op_dbvc_16, m68k_op_dbvc_16, m68k_op_dbvc_16, m68k_op_dbvc_16, m68k_op_dbvc_16, m68k_op_dbvc_16, m68k_op_dbvc_16, m68k_op_dbvc_16, + m68k_op_svc_8_ai, m68k_op_svc_8_ai, m68k_op_svc_8_ai, m68k_op_svc_8_ai, m68k_op_svc_8_ai, m68k_op_svc_8_ai, m68k_op_svc_8_ai, m68k_op_svc_8_ai, + m68k_op_svc_8_pi, m68k_op_svc_8_pi, m68k_op_svc_8_pi, m68k_op_svc_8_pi, m68k_op_svc_8_pi, m68k_op_svc_8_pi, m68k_op_svc_8_pi, m68k_op_svc_8_pi7, + m68k_op_svc_8_pd, m68k_op_svc_8_pd, m68k_op_svc_8_pd, m68k_op_svc_8_pd, m68k_op_svc_8_pd, m68k_op_svc_8_pd, m68k_op_svc_8_pd, m68k_op_svc_8_pd7, + m68k_op_svc_8_di, m68k_op_svc_8_di, m68k_op_svc_8_di, m68k_op_svc_8_di, m68k_op_svc_8_di, m68k_op_svc_8_di, m68k_op_svc_8_di, m68k_op_svc_8_di, + m68k_op_svc_8_ix, m68k_op_svc_8_ix, m68k_op_svc_8_ix, m68k_op_svc_8_ix, m68k_op_svc_8_ix, m68k_op_svc_8_ix, m68k_op_svc_8_ix, m68k_op_svc_8_ix, + m68k_op_svc_8_aw, m68k_op_svc_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, + m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi7, + m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd7, + m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, + m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, + m68k_op_subq_8_aw, m68k_op_subq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, + m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, + m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, + m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, + m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, + m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, + m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, + m68k_op_subq_16_aw, m68k_op_subq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, + m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, + m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, + m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, + m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, + m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, + m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, + m68k_op_subq_32_aw, m68k_op_subq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_svs_8_d, m68k_op_svs_8_d, m68k_op_svs_8_d, m68k_op_svs_8_d, m68k_op_svs_8_d, m68k_op_svs_8_d, m68k_op_svs_8_d, m68k_op_svs_8_d, + m68k_op_dbvs_16, m68k_op_dbvs_16, m68k_op_dbvs_16, m68k_op_dbvs_16, m68k_op_dbvs_16, m68k_op_dbvs_16, m68k_op_dbvs_16, m68k_op_dbvs_16, + m68k_op_svs_8_ai, m68k_op_svs_8_ai, m68k_op_svs_8_ai, m68k_op_svs_8_ai, m68k_op_svs_8_ai, m68k_op_svs_8_ai, m68k_op_svs_8_ai, m68k_op_svs_8_ai, + m68k_op_svs_8_pi, m68k_op_svs_8_pi, m68k_op_svs_8_pi, m68k_op_svs_8_pi, m68k_op_svs_8_pi, m68k_op_svs_8_pi, m68k_op_svs_8_pi, m68k_op_svs_8_pi7, + m68k_op_svs_8_pd, m68k_op_svs_8_pd, m68k_op_svs_8_pd, m68k_op_svs_8_pd, m68k_op_svs_8_pd, m68k_op_svs_8_pd, m68k_op_svs_8_pd, m68k_op_svs_8_pd7, + m68k_op_svs_8_di, m68k_op_svs_8_di, m68k_op_svs_8_di, m68k_op_svs_8_di, m68k_op_svs_8_di, m68k_op_svs_8_di, m68k_op_svs_8_di, m68k_op_svs_8_di, + m68k_op_svs_8_ix, m68k_op_svs_8_ix, m68k_op_svs_8_ix, m68k_op_svs_8_ix, m68k_op_svs_8_ix, m68k_op_svs_8_ix, m68k_op_svs_8_ix, m68k_op_svs_8_ix, + m68k_op_svs_8_aw, m68k_op_svs_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, + m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi7, + m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd7, + m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, + m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, + m68k_op_addq_8_aw, m68k_op_addq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, + m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, + m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, + m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, + m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, + m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, + m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, + m68k_op_addq_16_aw, m68k_op_addq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, + m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, + m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, + m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, + m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, + m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, + m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, + m68k_op_addq_32_aw, m68k_op_addq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_spl_8_d, m68k_op_spl_8_d, m68k_op_spl_8_d, m68k_op_spl_8_d, m68k_op_spl_8_d, m68k_op_spl_8_d, m68k_op_spl_8_d, m68k_op_spl_8_d, + m68k_op_dbpl_16, m68k_op_dbpl_16, m68k_op_dbpl_16, m68k_op_dbpl_16, m68k_op_dbpl_16, m68k_op_dbpl_16, m68k_op_dbpl_16, m68k_op_dbpl_16, + m68k_op_spl_8_ai, m68k_op_spl_8_ai, m68k_op_spl_8_ai, m68k_op_spl_8_ai, m68k_op_spl_8_ai, m68k_op_spl_8_ai, m68k_op_spl_8_ai, m68k_op_spl_8_ai, + m68k_op_spl_8_pi, m68k_op_spl_8_pi, m68k_op_spl_8_pi, m68k_op_spl_8_pi, m68k_op_spl_8_pi, m68k_op_spl_8_pi, m68k_op_spl_8_pi, m68k_op_spl_8_pi7, + m68k_op_spl_8_pd, m68k_op_spl_8_pd, m68k_op_spl_8_pd, m68k_op_spl_8_pd, m68k_op_spl_8_pd, m68k_op_spl_8_pd, m68k_op_spl_8_pd, m68k_op_spl_8_pd7, + m68k_op_spl_8_di, m68k_op_spl_8_di, m68k_op_spl_8_di, m68k_op_spl_8_di, m68k_op_spl_8_di, m68k_op_spl_8_di, m68k_op_spl_8_di, m68k_op_spl_8_di, + m68k_op_spl_8_ix, m68k_op_spl_8_ix, m68k_op_spl_8_ix, m68k_op_spl_8_ix, m68k_op_spl_8_ix, m68k_op_spl_8_ix, m68k_op_spl_8_ix, m68k_op_spl_8_ix, + m68k_op_spl_8_aw, m68k_op_spl_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, + m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi7, + m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd7, + m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, + m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, + m68k_op_subq_8_aw, m68k_op_subq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, + m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, + m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, + m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, + m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, + m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, + m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, + m68k_op_subq_16_aw, m68k_op_subq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, + m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, + m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, + m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, + m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, + m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, + m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, + m68k_op_subq_32_aw, m68k_op_subq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_smi_8_d, m68k_op_smi_8_d, m68k_op_smi_8_d, m68k_op_smi_8_d, m68k_op_smi_8_d, m68k_op_smi_8_d, m68k_op_smi_8_d, m68k_op_smi_8_d, + m68k_op_dbmi_16, m68k_op_dbmi_16, m68k_op_dbmi_16, m68k_op_dbmi_16, m68k_op_dbmi_16, m68k_op_dbmi_16, m68k_op_dbmi_16, m68k_op_dbmi_16, + m68k_op_smi_8_ai, m68k_op_smi_8_ai, m68k_op_smi_8_ai, m68k_op_smi_8_ai, m68k_op_smi_8_ai, m68k_op_smi_8_ai, m68k_op_smi_8_ai, m68k_op_smi_8_ai, + m68k_op_smi_8_pi, m68k_op_smi_8_pi, m68k_op_smi_8_pi, m68k_op_smi_8_pi, m68k_op_smi_8_pi, m68k_op_smi_8_pi, m68k_op_smi_8_pi, m68k_op_smi_8_pi7, + m68k_op_smi_8_pd, m68k_op_smi_8_pd, m68k_op_smi_8_pd, m68k_op_smi_8_pd, m68k_op_smi_8_pd, m68k_op_smi_8_pd, m68k_op_smi_8_pd, m68k_op_smi_8_pd7, + m68k_op_smi_8_di, m68k_op_smi_8_di, m68k_op_smi_8_di, m68k_op_smi_8_di, m68k_op_smi_8_di, m68k_op_smi_8_di, m68k_op_smi_8_di, m68k_op_smi_8_di, + m68k_op_smi_8_ix, m68k_op_smi_8_ix, m68k_op_smi_8_ix, m68k_op_smi_8_ix, m68k_op_smi_8_ix, m68k_op_smi_8_ix, m68k_op_smi_8_ix, m68k_op_smi_8_ix, + m68k_op_smi_8_aw, m68k_op_smi_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, + m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi7, + m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd7, + m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, + m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, + m68k_op_addq_8_aw, m68k_op_addq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, + m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, + m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, + m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, + m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, + m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, + m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, + m68k_op_addq_16_aw, m68k_op_addq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, + m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, + m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, + m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, + m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, + m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, + m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, + m68k_op_addq_32_aw, m68k_op_addq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sge_8_d, m68k_op_sge_8_d, m68k_op_sge_8_d, m68k_op_sge_8_d, m68k_op_sge_8_d, m68k_op_sge_8_d, m68k_op_sge_8_d, m68k_op_sge_8_d, + m68k_op_dbge_16, m68k_op_dbge_16, m68k_op_dbge_16, m68k_op_dbge_16, m68k_op_dbge_16, m68k_op_dbge_16, m68k_op_dbge_16, m68k_op_dbge_16, + m68k_op_sge_8_ai, m68k_op_sge_8_ai, m68k_op_sge_8_ai, m68k_op_sge_8_ai, m68k_op_sge_8_ai, m68k_op_sge_8_ai, m68k_op_sge_8_ai, m68k_op_sge_8_ai, + m68k_op_sge_8_pi, m68k_op_sge_8_pi, m68k_op_sge_8_pi, m68k_op_sge_8_pi, m68k_op_sge_8_pi, m68k_op_sge_8_pi, m68k_op_sge_8_pi, m68k_op_sge_8_pi7, + m68k_op_sge_8_pd, m68k_op_sge_8_pd, m68k_op_sge_8_pd, m68k_op_sge_8_pd, m68k_op_sge_8_pd, m68k_op_sge_8_pd, m68k_op_sge_8_pd, m68k_op_sge_8_pd7, + m68k_op_sge_8_di, m68k_op_sge_8_di, m68k_op_sge_8_di, m68k_op_sge_8_di, m68k_op_sge_8_di, m68k_op_sge_8_di, m68k_op_sge_8_di, m68k_op_sge_8_di, + m68k_op_sge_8_ix, m68k_op_sge_8_ix, m68k_op_sge_8_ix, m68k_op_sge_8_ix, m68k_op_sge_8_ix, m68k_op_sge_8_ix, m68k_op_sge_8_ix, m68k_op_sge_8_ix, + m68k_op_sge_8_aw, m68k_op_sge_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, + m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi7, + m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd7, + m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, + m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, + m68k_op_subq_8_aw, m68k_op_subq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, + m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, + m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, + m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, + m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, + m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, + m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, + m68k_op_subq_16_aw, m68k_op_subq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, + m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, + m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, + m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, + m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, + m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, + m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, + m68k_op_subq_32_aw, m68k_op_subq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_slt_8_d, m68k_op_slt_8_d, m68k_op_slt_8_d, m68k_op_slt_8_d, m68k_op_slt_8_d, m68k_op_slt_8_d, m68k_op_slt_8_d, m68k_op_slt_8_d, + m68k_op_dblt_16, m68k_op_dblt_16, m68k_op_dblt_16, m68k_op_dblt_16, m68k_op_dblt_16, m68k_op_dblt_16, m68k_op_dblt_16, m68k_op_dblt_16, + m68k_op_slt_8_ai, m68k_op_slt_8_ai, m68k_op_slt_8_ai, m68k_op_slt_8_ai, m68k_op_slt_8_ai, m68k_op_slt_8_ai, m68k_op_slt_8_ai, m68k_op_slt_8_ai, + m68k_op_slt_8_pi, m68k_op_slt_8_pi, m68k_op_slt_8_pi, m68k_op_slt_8_pi, m68k_op_slt_8_pi, m68k_op_slt_8_pi, m68k_op_slt_8_pi, m68k_op_slt_8_pi7, + m68k_op_slt_8_pd, m68k_op_slt_8_pd, m68k_op_slt_8_pd, m68k_op_slt_8_pd, m68k_op_slt_8_pd, m68k_op_slt_8_pd, m68k_op_slt_8_pd, m68k_op_slt_8_pd7, + m68k_op_slt_8_di, m68k_op_slt_8_di, m68k_op_slt_8_di, m68k_op_slt_8_di, m68k_op_slt_8_di, m68k_op_slt_8_di, m68k_op_slt_8_di, m68k_op_slt_8_di, + m68k_op_slt_8_ix, m68k_op_slt_8_ix, m68k_op_slt_8_ix, m68k_op_slt_8_ix, m68k_op_slt_8_ix, m68k_op_slt_8_ix, m68k_op_slt_8_ix, m68k_op_slt_8_ix, + m68k_op_slt_8_aw, m68k_op_slt_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, m68k_op_addq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, m68k_op_addq_8_ai, + m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi, m68k_op_addq_8_pi7, + m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd, m68k_op_addq_8_pd7, + m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, m68k_op_addq_8_di, + m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, m68k_op_addq_8_ix, + m68k_op_addq_8_aw, m68k_op_addq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, m68k_op_addq_16_d, + m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, m68k_op_addq_16_a, + m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, m68k_op_addq_16_ai, + m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, m68k_op_addq_16_pi, + m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, m68k_op_addq_16_pd, + m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, m68k_op_addq_16_di, + m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, m68k_op_addq_16_ix, + m68k_op_addq_16_aw, m68k_op_addq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, m68k_op_addq_32_d, + m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, m68k_op_addq_32_a, + m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, m68k_op_addq_32_ai, + m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, m68k_op_addq_32_pi, + m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, m68k_op_addq_32_pd, + m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, m68k_op_addq_32_di, + m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, m68k_op_addq_32_ix, + m68k_op_addq_32_aw, m68k_op_addq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sgt_8_d, m68k_op_sgt_8_d, m68k_op_sgt_8_d, m68k_op_sgt_8_d, m68k_op_sgt_8_d, m68k_op_sgt_8_d, m68k_op_sgt_8_d, m68k_op_sgt_8_d, + m68k_op_dbgt_16, m68k_op_dbgt_16, m68k_op_dbgt_16, m68k_op_dbgt_16, m68k_op_dbgt_16, m68k_op_dbgt_16, m68k_op_dbgt_16, m68k_op_dbgt_16, + m68k_op_sgt_8_ai, m68k_op_sgt_8_ai, m68k_op_sgt_8_ai, m68k_op_sgt_8_ai, m68k_op_sgt_8_ai, m68k_op_sgt_8_ai, m68k_op_sgt_8_ai, m68k_op_sgt_8_ai, + m68k_op_sgt_8_pi, m68k_op_sgt_8_pi, m68k_op_sgt_8_pi, m68k_op_sgt_8_pi, m68k_op_sgt_8_pi, m68k_op_sgt_8_pi, m68k_op_sgt_8_pi, m68k_op_sgt_8_pi7, + m68k_op_sgt_8_pd, m68k_op_sgt_8_pd, m68k_op_sgt_8_pd, m68k_op_sgt_8_pd, m68k_op_sgt_8_pd, m68k_op_sgt_8_pd, m68k_op_sgt_8_pd, m68k_op_sgt_8_pd7, + m68k_op_sgt_8_di, m68k_op_sgt_8_di, m68k_op_sgt_8_di, m68k_op_sgt_8_di, m68k_op_sgt_8_di, m68k_op_sgt_8_di, m68k_op_sgt_8_di, m68k_op_sgt_8_di, + m68k_op_sgt_8_ix, m68k_op_sgt_8_ix, m68k_op_sgt_8_ix, m68k_op_sgt_8_ix, m68k_op_sgt_8_ix, m68k_op_sgt_8_ix, m68k_op_sgt_8_ix, m68k_op_sgt_8_ix, + m68k_op_sgt_8_aw, m68k_op_sgt_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, m68k_op_subq_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, m68k_op_subq_8_ai, + m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi, m68k_op_subq_8_pi7, + m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd, m68k_op_subq_8_pd7, + m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, m68k_op_subq_8_di, + m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, m68k_op_subq_8_ix, + m68k_op_subq_8_aw, m68k_op_subq_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, m68k_op_subq_16_d, + m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, m68k_op_subq_16_a, + m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, m68k_op_subq_16_ai, + m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, m68k_op_subq_16_pi, + m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, m68k_op_subq_16_pd, + m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, m68k_op_subq_16_di, + m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, m68k_op_subq_16_ix, + m68k_op_subq_16_aw, m68k_op_subq_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, m68k_op_subq_32_d, + m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, m68k_op_subq_32_a, + m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, m68k_op_subq_32_ai, + m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, m68k_op_subq_32_pi, + m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, m68k_op_subq_32_pd, + m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, m68k_op_subq_32_di, + m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, m68k_op_subq_32_ix, + m68k_op_subq_32_aw, m68k_op_subq_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sle_8_d, m68k_op_sle_8_d, m68k_op_sle_8_d, m68k_op_sle_8_d, m68k_op_sle_8_d, m68k_op_sle_8_d, m68k_op_sle_8_d, m68k_op_sle_8_d, + m68k_op_dble_16, m68k_op_dble_16, m68k_op_dble_16, m68k_op_dble_16, m68k_op_dble_16, m68k_op_dble_16, m68k_op_dble_16, m68k_op_dble_16, + m68k_op_sle_8_ai, m68k_op_sle_8_ai, m68k_op_sle_8_ai, m68k_op_sle_8_ai, m68k_op_sle_8_ai, m68k_op_sle_8_ai, m68k_op_sle_8_ai, m68k_op_sle_8_ai, + m68k_op_sle_8_pi, m68k_op_sle_8_pi, m68k_op_sle_8_pi, m68k_op_sle_8_pi, m68k_op_sle_8_pi, m68k_op_sle_8_pi, m68k_op_sle_8_pi, m68k_op_sle_8_pi7, + m68k_op_sle_8_pd, m68k_op_sle_8_pd, m68k_op_sle_8_pd, m68k_op_sle_8_pd, m68k_op_sle_8_pd, m68k_op_sle_8_pd, m68k_op_sle_8_pd, m68k_op_sle_8_pd7, + m68k_op_sle_8_di, m68k_op_sle_8_di, m68k_op_sle_8_di, m68k_op_sle_8_di, m68k_op_sle_8_di, m68k_op_sle_8_di, m68k_op_sle_8_di, m68k_op_sle_8_di, + m68k_op_sle_8_ix, m68k_op_sle_8_ix, m68k_op_sle_8_ix, m68k_op_sle_8_ix, m68k_op_sle_8_ix, m68k_op_sle_8_ix, m68k_op_sle_8_ix, m68k_op_sle_8_ix, + m68k_op_sle_8_aw, m68k_op_sle_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_bra_16, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, + m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_8, m68k_op_bra_32, + m68k_op_bsr_16, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, + m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_8, m68k_op_bsr_32, + m68k_op_bhi_16, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, + m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_8, m68k_op_bhi_32, + m68k_op_bls_16, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, + m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_8, m68k_op_bls_32, + m68k_op_bcc_16, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, + m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_8, m68k_op_bcc_32, + m68k_op_bcs_16, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, + m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_8, m68k_op_bcs_32, + m68k_op_bne_16, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, + m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_8, m68k_op_bne_32, + m68k_op_beq_16, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, + m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_8, m68k_op_beq_32, + m68k_op_bvc_16, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, + m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_8, m68k_op_bvc_32, + m68k_op_bvs_16, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, + m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_8, m68k_op_bvs_32, + m68k_op_bpl_16, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, + m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_8, m68k_op_bpl_32, + m68k_op_bmi_16, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, + m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_8, m68k_op_bmi_32, + m68k_op_bge_16, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, + m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_8, m68k_op_bge_32, + m68k_op_blt_16, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, + m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_8, m68k_op_blt_32, + m68k_op_bgt_16, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, + m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_8, m68k_op_bgt_32, + m68k_op_ble_16, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, + m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_8, m68k_op_ble_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, m68k_op_moveq_32, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, + m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi7, + m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd7, + m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, + m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, + m68k_op_or_8_er_aw, m68k_op_or_8_er_al, m68k_op_or_8_er_pcdi, m68k_op_or_8_er_pcix, m68k_op_or_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, + m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, + m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, + m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, + m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, + m68k_op_or_16_er_aw, m68k_op_or_16_er_al, m68k_op_or_16_er_pcdi, m68k_op_or_16_er_pcix, m68k_op_or_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, + m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, + m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, + m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, + m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, + m68k_op_or_32_er_aw, m68k_op_or_32_er_al, m68k_op_or_32_er_pcdi, m68k_op_or_32_er_pcix, m68k_op_or_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, + m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, + m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, + m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, + m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, + m68k_op_divu_16_aw, m68k_op_divu_16_al, m68k_op_divu_16_pcdi, m68k_op_divu_16_pcix, m68k_op_divu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, + m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm_ay7, + m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, + m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi7, + m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd7, + m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, + m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, + m68k_op_or_8_re_aw, m68k_op_or_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, + m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, + m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, + m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, + m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, + m68k_op_or_16_re_aw, m68k_op_or_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, + m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, + m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, + m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, + m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, + m68k_op_or_32_re_aw, m68k_op_or_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, + m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, + m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, + m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, + m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, + m68k_op_divs_16_aw, m68k_op_divs_16_al, m68k_op_divs_16_pcdi, m68k_op_divs_16_pcix, m68k_op_divs_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, + m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi7, + m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd7, + m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, + m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, + m68k_op_or_8_er_aw, m68k_op_or_8_er_al, m68k_op_or_8_er_pcdi, m68k_op_or_8_er_pcix, m68k_op_or_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, + m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, + m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, + m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, + m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, + m68k_op_or_16_er_aw, m68k_op_or_16_er_al, m68k_op_or_16_er_pcdi, m68k_op_or_16_er_pcix, m68k_op_or_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, + m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, + m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, + m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, + m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, + m68k_op_or_32_er_aw, m68k_op_or_32_er_al, m68k_op_or_32_er_pcdi, m68k_op_or_32_er_pcix, m68k_op_or_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, + m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, + m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, + m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, + m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, + m68k_op_divu_16_aw, m68k_op_divu_16_al, m68k_op_divu_16_pcdi, m68k_op_divu_16_pcix, m68k_op_divu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, + m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm_ay7, + m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, + m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi7, + m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd7, + m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, + m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, + m68k_op_or_8_re_aw, m68k_op_or_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, + m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, + m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, + m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, + m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, + m68k_op_or_16_re_aw, m68k_op_or_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, + m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, + m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, + m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, + m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, + m68k_op_or_32_re_aw, m68k_op_or_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, + m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, + m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, + m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, + m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, + m68k_op_divs_16_aw, m68k_op_divs_16_al, m68k_op_divs_16_pcdi, m68k_op_divs_16_pcix, m68k_op_divs_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, + m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi7, + m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd7, + m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, + m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, + m68k_op_or_8_er_aw, m68k_op_or_8_er_al, m68k_op_or_8_er_pcdi, m68k_op_or_8_er_pcix, m68k_op_or_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, + m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, + m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, + m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, + m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, + m68k_op_or_16_er_aw, m68k_op_or_16_er_al, m68k_op_or_16_er_pcdi, m68k_op_or_16_er_pcix, m68k_op_or_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, + m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, + m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, + m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, + m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, + m68k_op_or_32_er_aw, m68k_op_or_32_er_al, m68k_op_or_32_er_pcdi, m68k_op_or_32_er_pcix, m68k_op_or_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, + m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, + m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, + m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, + m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, + m68k_op_divu_16_aw, m68k_op_divu_16_al, m68k_op_divu_16_pcdi, m68k_op_divu_16_pcix, m68k_op_divu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, + m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm_ay7, + m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, + m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi7, + m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd7, + m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, + m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, + m68k_op_or_8_re_aw, m68k_op_or_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, + m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, + m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, + m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, + m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, + m68k_op_or_16_re_aw, m68k_op_or_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, + m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, + m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, + m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, + m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, + m68k_op_or_32_re_aw, m68k_op_or_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, + m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, + m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, + m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, + m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, + m68k_op_divs_16_aw, m68k_op_divs_16_al, m68k_op_divs_16_pcdi, m68k_op_divs_16_pcix, m68k_op_divs_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, + m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi7, + m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd7, + m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, + m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, + m68k_op_or_8_er_aw, m68k_op_or_8_er_al, m68k_op_or_8_er_pcdi, m68k_op_or_8_er_pcix, m68k_op_or_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, + m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, + m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, + m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, + m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, + m68k_op_or_16_er_aw, m68k_op_or_16_er_al, m68k_op_or_16_er_pcdi, m68k_op_or_16_er_pcix, m68k_op_or_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, + m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, + m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, + m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, + m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, + m68k_op_or_32_er_aw, m68k_op_or_32_er_al, m68k_op_or_32_er_pcdi, m68k_op_or_32_er_pcix, m68k_op_or_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, + m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, + m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, + m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, + m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, + m68k_op_divu_16_aw, m68k_op_divu_16_al, m68k_op_divu_16_pcdi, m68k_op_divu_16_pcix, m68k_op_divu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, + m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm_ay7, + m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, + m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi7, + m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd7, + m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, + m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, + m68k_op_or_8_re_aw, m68k_op_or_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, + m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, + m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, + m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, + m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, + m68k_op_or_16_re_aw, m68k_op_or_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, + m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, + m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, + m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, + m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, + m68k_op_or_32_re_aw, m68k_op_or_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, + m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, + m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, + m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, + m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, + m68k_op_divs_16_aw, m68k_op_divs_16_al, m68k_op_divs_16_pcdi, m68k_op_divs_16_pcix, m68k_op_divs_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, + m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi7, + m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd7, + m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, + m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, + m68k_op_or_8_er_aw, m68k_op_or_8_er_al, m68k_op_or_8_er_pcdi, m68k_op_or_8_er_pcix, m68k_op_or_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, + m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, + m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, + m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, + m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, + m68k_op_or_16_er_aw, m68k_op_or_16_er_al, m68k_op_or_16_er_pcdi, m68k_op_or_16_er_pcix, m68k_op_or_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, + m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, + m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, + m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, + m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, + m68k_op_or_32_er_aw, m68k_op_or_32_er_al, m68k_op_or_32_er_pcdi, m68k_op_or_32_er_pcix, m68k_op_or_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, + m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, + m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, + m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, + m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, + m68k_op_divu_16_aw, m68k_op_divu_16_al, m68k_op_divu_16_pcdi, m68k_op_divu_16_pcix, m68k_op_divu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, + m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm_ay7, + m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, + m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi7, + m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd7, + m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, + m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, + m68k_op_or_8_re_aw, m68k_op_or_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, + m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, + m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, + m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, + m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, + m68k_op_or_16_re_aw, m68k_op_or_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, + m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, + m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, + m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, + m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, + m68k_op_or_32_re_aw, m68k_op_or_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, + m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, + m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, + m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, + m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, + m68k_op_divs_16_aw, m68k_op_divs_16_al, m68k_op_divs_16_pcdi, m68k_op_divs_16_pcix, m68k_op_divs_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, + m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi7, + m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd7, + m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, + m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, + m68k_op_or_8_er_aw, m68k_op_or_8_er_al, m68k_op_or_8_er_pcdi, m68k_op_or_8_er_pcix, m68k_op_or_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, + m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, + m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, + m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, + m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, + m68k_op_or_16_er_aw, m68k_op_or_16_er_al, m68k_op_or_16_er_pcdi, m68k_op_or_16_er_pcix, m68k_op_or_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, + m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, + m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, + m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, + m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, + m68k_op_or_32_er_aw, m68k_op_or_32_er_al, m68k_op_or_32_er_pcdi, m68k_op_or_32_er_pcix, m68k_op_or_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, + m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, + m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, + m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, + m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, + m68k_op_divu_16_aw, m68k_op_divu_16_al, m68k_op_divu_16_pcdi, m68k_op_divu_16_pcix, m68k_op_divu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, + m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm_ay7, + m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, + m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi7, + m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd7, + m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, + m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, + m68k_op_or_8_re_aw, m68k_op_or_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, + m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, + m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, + m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, + m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, + m68k_op_or_16_re_aw, m68k_op_or_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, + m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, + m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, + m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, + m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, + m68k_op_or_32_re_aw, m68k_op_or_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, + m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, + m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, + m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, + m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, + m68k_op_divs_16_aw, m68k_op_divs_16_al, m68k_op_divs_16_pcdi, m68k_op_divs_16_pcix, m68k_op_divs_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, + m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi7, + m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd7, + m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, + m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, + m68k_op_or_8_er_aw, m68k_op_or_8_er_al, m68k_op_or_8_er_pcdi, m68k_op_or_8_er_pcix, m68k_op_or_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, + m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, + m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, + m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, + m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, + m68k_op_or_16_er_aw, m68k_op_or_16_er_al, m68k_op_or_16_er_pcdi, m68k_op_or_16_er_pcix, m68k_op_or_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, + m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, + m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, + m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, + m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, + m68k_op_or_32_er_aw, m68k_op_or_32_er_al, m68k_op_or_32_er_pcdi, m68k_op_or_32_er_pcix, m68k_op_or_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, + m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, + m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, + m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, + m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, + m68k_op_divu_16_aw, m68k_op_divu_16_al, m68k_op_divu_16_pcdi, m68k_op_divu_16_pcix, m68k_op_divu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, + m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm, m68k_op_sbcd_8_mm_ay7, + m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, + m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi7, + m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd7, + m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, + m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, + m68k_op_or_8_re_aw, m68k_op_or_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, + m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, + m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, + m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, + m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, + m68k_op_or_16_re_aw, m68k_op_or_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, + m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, + m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, + m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, + m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, + m68k_op_or_32_re_aw, m68k_op_or_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, + m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, + m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, + m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, + m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, + m68k_op_divs_16_aw, m68k_op_divs_16_al, m68k_op_divs_16_pcdi, m68k_op_divs_16_pcix, m68k_op_divs_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, m68k_op_or_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, m68k_op_or_8_er_ai, + m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi, m68k_op_or_8_er_pi7, + m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd, m68k_op_or_8_er_pd7, + m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, m68k_op_or_8_er_di, + m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, m68k_op_or_8_er_ix, + m68k_op_or_8_er_aw, m68k_op_or_8_er_al, m68k_op_or_8_er_pcdi, m68k_op_or_8_er_pcix, m68k_op_or_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, m68k_op_or_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, m68k_op_or_16_er_ai, + m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, m68k_op_or_16_er_pi, + m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, m68k_op_or_16_er_pd, + m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, m68k_op_or_16_er_di, + m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, m68k_op_or_16_er_ix, + m68k_op_or_16_er_aw, m68k_op_or_16_er_al, m68k_op_or_16_er_pcdi, m68k_op_or_16_er_pcix, m68k_op_or_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, m68k_op_or_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, m68k_op_or_32_er_ai, + m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, m68k_op_or_32_er_pi, + m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, m68k_op_or_32_er_pd, + m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, m68k_op_or_32_er_di, + m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, m68k_op_or_32_er_ix, + m68k_op_or_32_er_aw, m68k_op_or_32_er_al, m68k_op_or_32_er_pcdi, m68k_op_or_32_er_pcix, m68k_op_or_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, m68k_op_divu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, m68k_op_divu_16_ai, + m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, m68k_op_divu_16_pi, + m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, m68k_op_divu_16_pd, + m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, m68k_op_divu_16_di, + m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, m68k_op_divu_16_ix, + m68k_op_divu_16_aw, m68k_op_divu_16_al, m68k_op_divu_16_pcdi, m68k_op_divu_16_pcix, m68k_op_divu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, m68k_op_sbcd_8_rr, + m68k_op_sbcd_8_mm_ax7, m68k_op_sbcd_8_mm_ax7, m68k_op_sbcd_8_mm_ax7, m68k_op_sbcd_8_mm_ax7, m68k_op_sbcd_8_mm_ax7, m68k_op_sbcd_8_mm_ax7, m68k_op_sbcd_8_mm_ax7, m68k_op_sbcd_8_mm_axy7, + m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, m68k_op_or_8_re_ai, + m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi, m68k_op_or_8_re_pi7, + m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd, m68k_op_or_8_re_pd7, + m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, m68k_op_or_8_re_di, + m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, m68k_op_or_8_re_ix, + m68k_op_or_8_re_aw, m68k_op_or_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, m68k_op_or_16_re_ai, + m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, m68k_op_or_16_re_pi, + m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, m68k_op_or_16_re_pd, + m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, m68k_op_or_16_re_di, + m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, m68k_op_or_16_re_ix, + m68k_op_or_16_re_aw, m68k_op_or_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, m68k_op_or_32_re_ai, + m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, m68k_op_or_32_re_pi, + m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, m68k_op_or_32_re_pd, + m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, m68k_op_or_32_re_di, + m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, m68k_op_or_32_re_ix, + m68k_op_or_32_re_aw, m68k_op_or_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, m68k_op_divs_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, m68k_op_divs_16_ai, + m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, m68k_op_divs_16_pi, + m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, m68k_op_divs_16_pd, + m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, m68k_op_divs_16_di, + m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, m68k_op_divs_16_ix, + m68k_op_divs_16_aw, m68k_op_divs_16_al, m68k_op_divs_16_pcdi, m68k_op_divs_16_pcix, m68k_op_divs_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, + m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi7, + m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd7, + m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, + m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, + m68k_op_sub_8_er_aw, m68k_op_sub_8_er_al, m68k_op_sub_8_er_pcdi, m68k_op_sub_8_er_pcix, m68k_op_sub_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, + m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, + m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, + m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, + m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, + m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, + m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, + m68k_op_sub_16_er_aw, m68k_op_sub_16_er_al, m68k_op_sub_16_er_pcdi, m68k_op_sub_16_er_pcix, m68k_op_sub_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, + m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, + m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, + m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, + m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, + m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, + m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, + m68k_op_sub_32_er_aw, m68k_op_sub_32_er_al, m68k_op_sub_32_er_pcdi, m68k_op_sub_32_er_pcix, m68k_op_sub_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, + m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, + m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, + m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, + m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, + m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, + m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, + m68k_op_suba_16_aw, m68k_op_suba_16_al, m68k_op_suba_16_pcdi, m68k_op_suba_16_pcix, m68k_op_suba_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, + m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm_ay7, + m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, + m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi7, + m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd7, + m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, + m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, + m68k_op_sub_8_re_aw, m68k_op_sub_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, + m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, + m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, + m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, + m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, + m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, + m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, + m68k_op_sub_16_re_aw, m68k_op_sub_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, + m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, + m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, + m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, + m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, + m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, + m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, + m68k_op_sub_32_re_aw, m68k_op_sub_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, + m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, + m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, + m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, + m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, + m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, + m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, + m68k_op_suba_32_aw, m68k_op_suba_32_al, m68k_op_suba_32_pcdi, m68k_op_suba_32_pcix, m68k_op_suba_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, + m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi7, + m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd7, + m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, + m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, + m68k_op_sub_8_er_aw, m68k_op_sub_8_er_al, m68k_op_sub_8_er_pcdi, m68k_op_sub_8_er_pcix, m68k_op_sub_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, + m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, + m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, + m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, + m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, + m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, + m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, + m68k_op_sub_16_er_aw, m68k_op_sub_16_er_al, m68k_op_sub_16_er_pcdi, m68k_op_sub_16_er_pcix, m68k_op_sub_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, + m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, + m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, + m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, + m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, + m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, + m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, + m68k_op_sub_32_er_aw, m68k_op_sub_32_er_al, m68k_op_sub_32_er_pcdi, m68k_op_sub_32_er_pcix, m68k_op_sub_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, + m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, + m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, + m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, + m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, + m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, + m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, + m68k_op_suba_16_aw, m68k_op_suba_16_al, m68k_op_suba_16_pcdi, m68k_op_suba_16_pcix, m68k_op_suba_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, + m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm_ay7, + m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, + m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi7, + m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd7, + m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, + m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, + m68k_op_sub_8_re_aw, m68k_op_sub_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, + m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, + m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, + m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, + m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, + m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, + m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, + m68k_op_sub_16_re_aw, m68k_op_sub_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, + m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, + m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, + m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, + m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, + m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, + m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, + m68k_op_sub_32_re_aw, m68k_op_sub_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, + m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, + m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, + m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, + m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, + m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, + m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, + m68k_op_suba_32_aw, m68k_op_suba_32_al, m68k_op_suba_32_pcdi, m68k_op_suba_32_pcix, m68k_op_suba_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, + m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi7, + m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd7, + m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, + m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, + m68k_op_sub_8_er_aw, m68k_op_sub_8_er_al, m68k_op_sub_8_er_pcdi, m68k_op_sub_8_er_pcix, m68k_op_sub_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, + m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, + m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, + m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, + m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, + m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, + m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, + m68k_op_sub_16_er_aw, m68k_op_sub_16_er_al, m68k_op_sub_16_er_pcdi, m68k_op_sub_16_er_pcix, m68k_op_sub_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, + m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, + m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, + m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, + m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, + m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, + m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, + m68k_op_sub_32_er_aw, m68k_op_sub_32_er_al, m68k_op_sub_32_er_pcdi, m68k_op_sub_32_er_pcix, m68k_op_sub_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, + m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, + m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, + m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, + m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, + m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, + m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, + m68k_op_suba_16_aw, m68k_op_suba_16_al, m68k_op_suba_16_pcdi, m68k_op_suba_16_pcix, m68k_op_suba_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, + m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm_ay7, + m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, + m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi7, + m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd7, + m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, + m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, + m68k_op_sub_8_re_aw, m68k_op_sub_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, + m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, + m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, + m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, + m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, + m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, + m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, + m68k_op_sub_16_re_aw, m68k_op_sub_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, + m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, + m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, + m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, + m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, + m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, + m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, + m68k_op_sub_32_re_aw, m68k_op_sub_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, + m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, + m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, + m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, + m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, + m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, + m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, + m68k_op_suba_32_aw, m68k_op_suba_32_al, m68k_op_suba_32_pcdi, m68k_op_suba_32_pcix, m68k_op_suba_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, + m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi7, + m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd7, + m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, + m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, + m68k_op_sub_8_er_aw, m68k_op_sub_8_er_al, m68k_op_sub_8_er_pcdi, m68k_op_sub_8_er_pcix, m68k_op_sub_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, + m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, + m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, + m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, + m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, + m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, + m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, + m68k_op_sub_16_er_aw, m68k_op_sub_16_er_al, m68k_op_sub_16_er_pcdi, m68k_op_sub_16_er_pcix, m68k_op_sub_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, + m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, + m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, + m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, + m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, + m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, + m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, + m68k_op_sub_32_er_aw, m68k_op_sub_32_er_al, m68k_op_sub_32_er_pcdi, m68k_op_sub_32_er_pcix, m68k_op_sub_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, + m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, + m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, + m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, + m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, + m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, + m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, + m68k_op_suba_16_aw, m68k_op_suba_16_al, m68k_op_suba_16_pcdi, m68k_op_suba_16_pcix, m68k_op_suba_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, + m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm_ay7, + m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, + m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi7, + m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd7, + m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, + m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, + m68k_op_sub_8_re_aw, m68k_op_sub_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, + m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, + m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, + m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, + m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, + m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, + m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, + m68k_op_sub_16_re_aw, m68k_op_sub_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, + m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, + m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, + m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, + m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, + m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, + m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, + m68k_op_sub_32_re_aw, m68k_op_sub_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, + m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, + m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, + m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, + m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, + m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, + m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, + m68k_op_suba_32_aw, m68k_op_suba_32_al, m68k_op_suba_32_pcdi, m68k_op_suba_32_pcix, m68k_op_suba_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, + m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi7, + m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd7, + m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, + m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, + m68k_op_sub_8_er_aw, m68k_op_sub_8_er_al, m68k_op_sub_8_er_pcdi, m68k_op_sub_8_er_pcix, m68k_op_sub_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, + m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, + m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, + m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, + m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, + m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, + m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, + m68k_op_sub_16_er_aw, m68k_op_sub_16_er_al, m68k_op_sub_16_er_pcdi, m68k_op_sub_16_er_pcix, m68k_op_sub_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, + m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, + m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, + m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, + m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, + m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, + m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, + m68k_op_sub_32_er_aw, m68k_op_sub_32_er_al, m68k_op_sub_32_er_pcdi, m68k_op_sub_32_er_pcix, m68k_op_sub_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, + m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, + m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, + m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, + m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, + m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, + m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, + m68k_op_suba_16_aw, m68k_op_suba_16_al, m68k_op_suba_16_pcdi, m68k_op_suba_16_pcix, m68k_op_suba_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, + m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm_ay7, + m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, + m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi7, + m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd7, + m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, + m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, + m68k_op_sub_8_re_aw, m68k_op_sub_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, + m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, + m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, + m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, + m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, + m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, + m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, + m68k_op_sub_16_re_aw, m68k_op_sub_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, + m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, + m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, + m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, + m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, + m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, + m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, + m68k_op_sub_32_re_aw, m68k_op_sub_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, + m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, + m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, + m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, + m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, + m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, + m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, + m68k_op_suba_32_aw, m68k_op_suba_32_al, m68k_op_suba_32_pcdi, m68k_op_suba_32_pcix, m68k_op_suba_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, + m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi7, + m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd7, + m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, + m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, + m68k_op_sub_8_er_aw, m68k_op_sub_8_er_al, m68k_op_sub_8_er_pcdi, m68k_op_sub_8_er_pcix, m68k_op_sub_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, + m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, + m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, + m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, + m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, + m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, + m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, + m68k_op_sub_16_er_aw, m68k_op_sub_16_er_al, m68k_op_sub_16_er_pcdi, m68k_op_sub_16_er_pcix, m68k_op_sub_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, + m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, + m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, + m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, + m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, + m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, + m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, + m68k_op_sub_32_er_aw, m68k_op_sub_32_er_al, m68k_op_sub_32_er_pcdi, m68k_op_sub_32_er_pcix, m68k_op_sub_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, + m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, + m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, + m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, + m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, + m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, + m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, + m68k_op_suba_16_aw, m68k_op_suba_16_al, m68k_op_suba_16_pcdi, m68k_op_suba_16_pcix, m68k_op_suba_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, + m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm_ay7, + m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, + m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi7, + m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd7, + m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, + m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, + m68k_op_sub_8_re_aw, m68k_op_sub_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, + m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, + m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, + m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, + m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, + m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, + m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, + m68k_op_sub_16_re_aw, m68k_op_sub_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, + m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, + m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, + m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, + m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, + m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, + m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, + m68k_op_sub_32_re_aw, m68k_op_sub_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, + m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, + m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, + m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, + m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, + m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, + m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, + m68k_op_suba_32_aw, m68k_op_suba_32_al, m68k_op_suba_32_pcdi, m68k_op_suba_32_pcix, m68k_op_suba_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, + m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi7, + m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd7, + m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, + m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, + m68k_op_sub_8_er_aw, m68k_op_sub_8_er_al, m68k_op_sub_8_er_pcdi, m68k_op_sub_8_er_pcix, m68k_op_sub_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, + m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, + m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, + m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, + m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, + m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, + m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, + m68k_op_sub_16_er_aw, m68k_op_sub_16_er_al, m68k_op_sub_16_er_pcdi, m68k_op_sub_16_er_pcix, m68k_op_sub_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, + m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, + m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, + m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, + m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, + m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, + m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, + m68k_op_sub_32_er_aw, m68k_op_sub_32_er_al, m68k_op_sub_32_er_pcdi, m68k_op_sub_32_er_pcix, m68k_op_sub_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, + m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, + m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, + m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, + m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, + m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, + m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, + m68k_op_suba_16_aw, m68k_op_suba_16_al, m68k_op_suba_16_pcdi, m68k_op_suba_16_pcix, m68k_op_suba_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, + m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm, m68k_op_subx_8_mm_ay7, + m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, + m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi7, + m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd7, + m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, + m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, + m68k_op_sub_8_re_aw, m68k_op_sub_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, + m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, + m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, + m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, + m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, + m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, + m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, + m68k_op_sub_16_re_aw, m68k_op_sub_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, + m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, + m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, + m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, + m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, + m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, + m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, + m68k_op_sub_32_re_aw, m68k_op_sub_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, + m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, + m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, + m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, + m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, + m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, + m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, + m68k_op_suba_32_aw, m68k_op_suba_32_al, m68k_op_suba_32_pcdi, m68k_op_suba_32_pcix, m68k_op_suba_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, m68k_op_sub_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, m68k_op_sub_8_er_ai, + m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi, m68k_op_sub_8_er_pi7, + m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd, m68k_op_sub_8_er_pd7, + m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, m68k_op_sub_8_er_di, + m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, m68k_op_sub_8_er_ix, + m68k_op_sub_8_er_aw, m68k_op_sub_8_er_al, m68k_op_sub_8_er_pcdi, m68k_op_sub_8_er_pcix, m68k_op_sub_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, m68k_op_sub_16_er_d, + m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, m68k_op_sub_16_er_a, + m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, m68k_op_sub_16_er_ai, + m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, m68k_op_sub_16_er_pi, + m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, m68k_op_sub_16_er_pd, + m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, m68k_op_sub_16_er_di, + m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, m68k_op_sub_16_er_ix, + m68k_op_sub_16_er_aw, m68k_op_sub_16_er_al, m68k_op_sub_16_er_pcdi, m68k_op_sub_16_er_pcix, m68k_op_sub_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, m68k_op_sub_32_er_d, + m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, m68k_op_sub_32_er_a, + m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, m68k_op_sub_32_er_ai, + m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, m68k_op_sub_32_er_pi, + m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, m68k_op_sub_32_er_pd, + m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, m68k_op_sub_32_er_di, + m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, m68k_op_sub_32_er_ix, + m68k_op_sub_32_er_aw, m68k_op_sub_32_er_al, m68k_op_sub_32_er_pcdi, m68k_op_sub_32_er_pcix, m68k_op_sub_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, m68k_op_suba_16_d, + m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, m68k_op_suba_16_a, + m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, m68k_op_suba_16_ai, + m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, m68k_op_suba_16_pi, + m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, m68k_op_suba_16_pd, + m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, m68k_op_suba_16_di, + m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, m68k_op_suba_16_ix, + m68k_op_suba_16_aw, m68k_op_suba_16_al, m68k_op_suba_16_pcdi, m68k_op_suba_16_pcix, m68k_op_suba_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, m68k_op_subx_8_rr, + m68k_op_subx_8_mm_ax7, m68k_op_subx_8_mm_ax7, m68k_op_subx_8_mm_ax7, m68k_op_subx_8_mm_ax7, m68k_op_subx_8_mm_ax7, m68k_op_subx_8_mm_ax7, m68k_op_subx_8_mm_ax7, m68k_op_subx_8_mm_axy7, + m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, m68k_op_sub_8_re_ai, + m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi, m68k_op_sub_8_re_pi7, + m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd, m68k_op_sub_8_re_pd7, + m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, m68k_op_sub_8_re_di, + m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, m68k_op_sub_8_re_ix, + m68k_op_sub_8_re_aw, m68k_op_sub_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, m68k_op_subx_16_rr, + m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, m68k_op_subx_16_mm, + m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, m68k_op_sub_16_re_ai, + m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, m68k_op_sub_16_re_pi, + m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, m68k_op_sub_16_re_pd, + m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, m68k_op_sub_16_re_di, + m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, m68k_op_sub_16_re_ix, + m68k_op_sub_16_re_aw, m68k_op_sub_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, m68k_op_subx_32_rr, + m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, m68k_op_subx_32_mm, + m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, m68k_op_sub_32_re_ai, + m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, m68k_op_sub_32_re_pi, + m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, m68k_op_sub_32_re_pd, + m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, m68k_op_sub_32_re_di, + m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, m68k_op_sub_32_re_ix, + m68k_op_sub_32_re_aw, m68k_op_sub_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, m68k_op_suba_32_d, + m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, m68k_op_suba_32_a, + m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, m68k_op_suba_32_ai, + m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, m68k_op_suba_32_pi, + m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, m68k_op_suba_32_pd, + m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, m68k_op_suba_32_di, + m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, m68k_op_suba_32_ix, + m68k_op_suba_32_aw, m68k_op_suba_32_al, m68k_op_suba_32_pcdi, m68k_op_suba_32_pcix, m68k_op_suba_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, m68k_op_1010, + m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, + m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi7, + m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd7, + m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, + m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, + m68k_op_cmp_8_aw, m68k_op_cmp_8_al, m68k_op_cmp_8_pcdi, m68k_op_cmp_8_pcix, m68k_op_cmp_8_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, + m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, + m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, + m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, + m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, + m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, + m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, + m68k_op_cmp_16_aw, m68k_op_cmp_16_al, m68k_op_cmp_16_pcdi, m68k_op_cmp_16_pcix, m68k_op_cmp_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, + m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, + m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, + m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, + m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, + m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, + m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, + m68k_op_cmp_32_aw, m68k_op_cmp_32_al, m68k_op_cmp_32_pcdi, m68k_op_cmp_32_pcix, m68k_op_cmp_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, + m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, + m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, + m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, + m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, + m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, + m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, + m68k_op_cmpa_16_aw, m68k_op_cmpa_16_al, m68k_op_cmpa_16_pcdi, m68k_op_cmpa_16_pcix, m68k_op_cmpa_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, + m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8_ay7, + m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, + m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi7, + m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd7, + m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, + m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, + m68k_op_eor_8_aw, m68k_op_eor_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, + m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, + m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, + m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, + m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, + m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, + m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, + m68k_op_eor_16_aw, m68k_op_eor_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, + m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, + m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, + m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, + m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, + m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, + m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, + m68k_op_eor_32_aw, m68k_op_eor_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, + m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, + m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, + m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, + m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, + m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, + m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, + m68k_op_cmpa_32_aw, m68k_op_cmpa_32_al, m68k_op_cmpa_32_pcdi, m68k_op_cmpa_32_pcix, m68k_op_cmpa_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, + m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi7, + m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd7, + m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, + m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, + m68k_op_cmp_8_aw, m68k_op_cmp_8_al, m68k_op_cmp_8_pcdi, m68k_op_cmp_8_pcix, m68k_op_cmp_8_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, + m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, + m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, + m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, + m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, + m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, + m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, + m68k_op_cmp_16_aw, m68k_op_cmp_16_al, m68k_op_cmp_16_pcdi, m68k_op_cmp_16_pcix, m68k_op_cmp_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, + m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, + m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, + m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, + m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, + m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, + m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, + m68k_op_cmp_32_aw, m68k_op_cmp_32_al, m68k_op_cmp_32_pcdi, m68k_op_cmp_32_pcix, m68k_op_cmp_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, + m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, + m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, + m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, + m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, + m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, + m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, + m68k_op_cmpa_16_aw, m68k_op_cmpa_16_al, m68k_op_cmpa_16_pcdi, m68k_op_cmpa_16_pcix, m68k_op_cmpa_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, + m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8_ay7, + m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, + m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi7, + m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd7, + m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, + m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, + m68k_op_eor_8_aw, m68k_op_eor_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, + m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, + m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, + m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, + m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, + m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, + m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, + m68k_op_eor_16_aw, m68k_op_eor_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, + m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, + m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, + m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, + m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, + m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, + m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, + m68k_op_eor_32_aw, m68k_op_eor_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, + m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, + m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, + m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, + m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, + m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, + m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, + m68k_op_cmpa_32_aw, m68k_op_cmpa_32_al, m68k_op_cmpa_32_pcdi, m68k_op_cmpa_32_pcix, m68k_op_cmpa_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, + m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi7, + m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd7, + m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, + m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, + m68k_op_cmp_8_aw, m68k_op_cmp_8_al, m68k_op_cmp_8_pcdi, m68k_op_cmp_8_pcix, m68k_op_cmp_8_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, + m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, + m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, + m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, + m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, + m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, + m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, + m68k_op_cmp_16_aw, m68k_op_cmp_16_al, m68k_op_cmp_16_pcdi, m68k_op_cmp_16_pcix, m68k_op_cmp_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, + m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, + m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, + m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, + m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, + m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, + m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, + m68k_op_cmp_32_aw, m68k_op_cmp_32_al, m68k_op_cmp_32_pcdi, m68k_op_cmp_32_pcix, m68k_op_cmp_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, + m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, + m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, + m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, + m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, + m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, + m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, + m68k_op_cmpa_16_aw, m68k_op_cmpa_16_al, m68k_op_cmpa_16_pcdi, m68k_op_cmpa_16_pcix, m68k_op_cmpa_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, + m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8_ay7, + m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, + m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi7, + m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd7, + m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, + m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, + m68k_op_eor_8_aw, m68k_op_eor_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, + m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, + m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, + m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, + m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, + m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, + m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, + m68k_op_eor_16_aw, m68k_op_eor_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, + m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, + m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, + m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, + m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, + m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, + m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, + m68k_op_eor_32_aw, m68k_op_eor_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, + m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, + m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, + m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, + m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, + m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, + m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, + m68k_op_cmpa_32_aw, m68k_op_cmpa_32_al, m68k_op_cmpa_32_pcdi, m68k_op_cmpa_32_pcix, m68k_op_cmpa_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, + m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi7, + m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd7, + m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, + m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, + m68k_op_cmp_8_aw, m68k_op_cmp_8_al, m68k_op_cmp_8_pcdi, m68k_op_cmp_8_pcix, m68k_op_cmp_8_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, + m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, + m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, + m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, + m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, + m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, + m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, + m68k_op_cmp_16_aw, m68k_op_cmp_16_al, m68k_op_cmp_16_pcdi, m68k_op_cmp_16_pcix, m68k_op_cmp_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, + m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, + m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, + m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, + m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, + m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, + m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, + m68k_op_cmp_32_aw, m68k_op_cmp_32_al, m68k_op_cmp_32_pcdi, m68k_op_cmp_32_pcix, m68k_op_cmp_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, + m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, + m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, + m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, + m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, + m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, + m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, + m68k_op_cmpa_16_aw, m68k_op_cmpa_16_al, m68k_op_cmpa_16_pcdi, m68k_op_cmpa_16_pcix, m68k_op_cmpa_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, + m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8_ay7, + m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, + m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi7, + m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd7, + m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, + m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, + m68k_op_eor_8_aw, m68k_op_eor_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, + m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, + m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, + m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, + m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, + m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, + m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, + m68k_op_eor_16_aw, m68k_op_eor_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, + m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, + m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, + m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, + m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, + m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, + m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, + m68k_op_eor_32_aw, m68k_op_eor_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, + m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, + m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, + m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, + m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, + m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, + m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, + m68k_op_cmpa_32_aw, m68k_op_cmpa_32_al, m68k_op_cmpa_32_pcdi, m68k_op_cmpa_32_pcix, m68k_op_cmpa_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, + m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi7, + m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd7, + m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, + m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, + m68k_op_cmp_8_aw, m68k_op_cmp_8_al, m68k_op_cmp_8_pcdi, m68k_op_cmp_8_pcix, m68k_op_cmp_8_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, + m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, + m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, + m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, + m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, + m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, + m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, + m68k_op_cmp_16_aw, m68k_op_cmp_16_al, m68k_op_cmp_16_pcdi, m68k_op_cmp_16_pcix, m68k_op_cmp_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, + m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, + m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, + m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, + m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, + m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, + m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, + m68k_op_cmp_32_aw, m68k_op_cmp_32_al, m68k_op_cmp_32_pcdi, m68k_op_cmp_32_pcix, m68k_op_cmp_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, + m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, + m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, + m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, + m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, + m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, + m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, + m68k_op_cmpa_16_aw, m68k_op_cmpa_16_al, m68k_op_cmpa_16_pcdi, m68k_op_cmpa_16_pcix, m68k_op_cmpa_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, + m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8_ay7, + m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, + m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi7, + m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd7, + m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, + m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, + m68k_op_eor_8_aw, m68k_op_eor_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, + m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, + m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, + m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, + m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, + m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, + m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, + m68k_op_eor_16_aw, m68k_op_eor_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, + m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, + m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, + m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, + m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, + m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, + m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, + m68k_op_eor_32_aw, m68k_op_eor_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, + m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, + m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, + m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, + m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, + m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, + m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, + m68k_op_cmpa_32_aw, m68k_op_cmpa_32_al, m68k_op_cmpa_32_pcdi, m68k_op_cmpa_32_pcix, m68k_op_cmpa_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, + m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi7, + m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd7, + m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, + m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, + m68k_op_cmp_8_aw, m68k_op_cmp_8_al, m68k_op_cmp_8_pcdi, m68k_op_cmp_8_pcix, m68k_op_cmp_8_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, + m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, + m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, + m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, + m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, + m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, + m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, + m68k_op_cmp_16_aw, m68k_op_cmp_16_al, m68k_op_cmp_16_pcdi, m68k_op_cmp_16_pcix, m68k_op_cmp_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, + m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, + m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, + m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, + m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, + m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, + m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, + m68k_op_cmp_32_aw, m68k_op_cmp_32_al, m68k_op_cmp_32_pcdi, m68k_op_cmp_32_pcix, m68k_op_cmp_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, + m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, + m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, + m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, + m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, + m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, + m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, + m68k_op_cmpa_16_aw, m68k_op_cmpa_16_al, m68k_op_cmpa_16_pcdi, m68k_op_cmpa_16_pcix, m68k_op_cmpa_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, + m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8_ay7, + m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, + m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi7, + m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd7, + m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, + m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, + m68k_op_eor_8_aw, m68k_op_eor_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, + m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, + m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, + m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, + m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, + m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, + m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, + m68k_op_eor_16_aw, m68k_op_eor_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, + m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, + m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, + m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, + m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, + m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, + m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, + m68k_op_eor_32_aw, m68k_op_eor_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, + m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, + m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, + m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, + m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, + m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, + m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, + m68k_op_cmpa_32_aw, m68k_op_cmpa_32_al, m68k_op_cmpa_32_pcdi, m68k_op_cmpa_32_pcix, m68k_op_cmpa_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, + m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi7, + m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd7, + m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, + m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, + m68k_op_cmp_8_aw, m68k_op_cmp_8_al, m68k_op_cmp_8_pcdi, m68k_op_cmp_8_pcix, m68k_op_cmp_8_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, + m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, + m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, + m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, + m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, + m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, + m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, + m68k_op_cmp_16_aw, m68k_op_cmp_16_al, m68k_op_cmp_16_pcdi, m68k_op_cmp_16_pcix, m68k_op_cmp_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, + m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, + m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, + m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, + m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, + m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, + m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, + m68k_op_cmp_32_aw, m68k_op_cmp_32_al, m68k_op_cmp_32_pcdi, m68k_op_cmp_32_pcix, m68k_op_cmp_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, + m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, + m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, + m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, + m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, + m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, + m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, + m68k_op_cmpa_16_aw, m68k_op_cmpa_16_al, m68k_op_cmpa_16_pcdi, m68k_op_cmpa_16_pcix, m68k_op_cmpa_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, + m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8, m68k_op_cmpm_8_ay7, + m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, + m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi7, + m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd7, + m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, + m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, + m68k_op_eor_8_aw, m68k_op_eor_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, + m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, + m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, + m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, + m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, + m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, + m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, + m68k_op_eor_16_aw, m68k_op_eor_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, + m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, + m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, + m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, + m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, + m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, + m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, + m68k_op_eor_32_aw, m68k_op_eor_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, + m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, + m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, + m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, + m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, + m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, + m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, + m68k_op_cmpa_32_aw, m68k_op_cmpa_32_al, m68k_op_cmpa_32_pcdi, m68k_op_cmpa_32_pcix, m68k_op_cmpa_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, m68k_op_cmp_8_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, m68k_op_cmp_8_ai, + m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi, m68k_op_cmp_8_pi7, + m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd, m68k_op_cmp_8_pd7, + m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, m68k_op_cmp_8_di, + m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, m68k_op_cmp_8_ix, + m68k_op_cmp_8_aw, m68k_op_cmp_8_al, m68k_op_cmp_8_pcdi, m68k_op_cmp_8_pcix, m68k_op_cmp_8_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, m68k_op_cmp_16_d, + m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, m68k_op_cmp_16_a, + m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, m68k_op_cmp_16_ai, + m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, m68k_op_cmp_16_pi, + m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, m68k_op_cmp_16_pd, + m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, m68k_op_cmp_16_di, + m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, m68k_op_cmp_16_ix, + m68k_op_cmp_16_aw, m68k_op_cmp_16_al, m68k_op_cmp_16_pcdi, m68k_op_cmp_16_pcix, m68k_op_cmp_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, m68k_op_cmp_32_d, + m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, m68k_op_cmp_32_a, + m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, m68k_op_cmp_32_ai, + m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, m68k_op_cmp_32_pi, + m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, m68k_op_cmp_32_pd, + m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, m68k_op_cmp_32_di, + m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, m68k_op_cmp_32_ix, + m68k_op_cmp_32_aw, m68k_op_cmp_32_al, m68k_op_cmp_32_pcdi, m68k_op_cmp_32_pcix, m68k_op_cmp_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, m68k_op_cmpa_16_d, + m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, m68k_op_cmpa_16_a, + m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, m68k_op_cmpa_16_ai, + m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, m68k_op_cmpa_16_pi, + m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, m68k_op_cmpa_16_pd, + m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, m68k_op_cmpa_16_di, + m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, m68k_op_cmpa_16_ix, + m68k_op_cmpa_16_aw, m68k_op_cmpa_16_al, m68k_op_cmpa_16_pcdi, m68k_op_cmpa_16_pcix, m68k_op_cmpa_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, m68k_op_eor_8_d, + m68k_op_cmpm_8_ax7, m68k_op_cmpm_8_ax7, m68k_op_cmpm_8_ax7, m68k_op_cmpm_8_ax7, m68k_op_cmpm_8_ax7, m68k_op_cmpm_8_ax7, m68k_op_cmpm_8_ax7, m68k_op_cmpm_8_axy7, + m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, m68k_op_eor_8_ai, + m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi, m68k_op_eor_8_pi7, + m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd, m68k_op_eor_8_pd7, + m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, m68k_op_eor_8_di, + m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, m68k_op_eor_8_ix, + m68k_op_eor_8_aw, m68k_op_eor_8_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, m68k_op_eor_16_d, + m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, m68k_op_cmpm_16, + m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, m68k_op_eor_16_ai, + m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, m68k_op_eor_16_pi, + m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, m68k_op_eor_16_pd, + m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, m68k_op_eor_16_di, + m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, m68k_op_eor_16_ix, + m68k_op_eor_16_aw, m68k_op_eor_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, m68k_op_eor_32_d, + m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, m68k_op_cmpm_32, + m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, m68k_op_eor_32_ai, + m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, m68k_op_eor_32_pi, + m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, m68k_op_eor_32_pd, + m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, m68k_op_eor_32_di, + m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, m68k_op_eor_32_ix, + m68k_op_eor_32_aw, m68k_op_eor_32_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, m68k_op_cmpa_32_d, + m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, m68k_op_cmpa_32_a, + m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, m68k_op_cmpa_32_ai, + m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, m68k_op_cmpa_32_pi, + m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, m68k_op_cmpa_32_pd, + m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, m68k_op_cmpa_32_di, + m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, m68k_op_cmpa_32_ix, + m68k_op_cmpa_32_aw, m68k_op_cmpa_32_al, m68k_op_cmpa_32_pcdi, m68k_op_cmpa_32_pcix, m68k_op_cmpa_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, + m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi7, + m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd7, + m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, + m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, + m68k_op_and_8_er_aw, m68k_op_and_8_er_al, m68k_op_and_8_er_pcdi, m68k_op_and_8_er_pcix, m68k_op_and_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, + m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, + m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, + m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, + m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, + m68k_op_and_16_er_aw, m68k_op_and_16_er_al, m68k_op_and_16_er_pcdi, m68k_op_and_16_er_pcix, m68k_op_and_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, + m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, + m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, + m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, + m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, + m68k_op_and_32_er_aw, m68k_op_and_32_er_al, m68k_op_and_32_er_pcdi, m68k_op_and_32_er_pcix, m68k_op_and_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, + m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, + m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, + m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, + m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, + m68k_op_mulu_16_aw, m68k_op_mulu_16_al, m68k_op_mulu_16_pcdi, m68k_op_mulu_16_pcix, m68k_op_mulu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, + m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm_ay7, + m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, + m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi7, + m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd7, + m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, + m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, + m68k_op_and_8_re_aw, m68k_op_and_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, + m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, + m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, + m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, + m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, + m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, + m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, + m68k_op_and_16_re_aw, m68k_op_and_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, + m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, + m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, + m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, + m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, + m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, + m68k_op_and_32_re_aw, m68k_op_and_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, + m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, + m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, + m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, + m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, + m68k_op_muls_16_aw, m68k_op_muls_16_al, m68k_op_muls_16_pcdi, m68k_op_muls_16_pcix, m68k_op_muls_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, + m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi7, + m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd7, + m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, + m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, + m68k_op_and_8_er_aw, m68k_op_and_8_er_al, m68k_op_and_8_er_pcdi, m68k_op_and_8_er_pcix, m68k_op_and_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, + m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, + m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, + m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, + m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, + m68k_op_and_16_er_aw, m68k_op_and_16_er_al, m68k_op_and_16_er_pcdi, m68k_op_and_16_er_pcix, m68k_op_and_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, + m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, + m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, + m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, + m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, + m68k_op_and_32_er_aw, m68k_op_and_32_er_al, m68k_op_and_32_er_pcdi, m68k_op_and_32_er_pcix, m68k_op_and_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, + m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, + m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, + m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, + m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, + m68k_op_mulu_16_aw, m68k_op_mulu_16_al, m68k_op_mulu_16_pcdi, m68k_op_mulu_16_pcix, m68k_op_mulu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, + m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm_ay7, + m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, + m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi7, + m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd7, + m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, + m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, + m68k_op_and_8_re_aw, m68k_op_and_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, + m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, + m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, + m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, + m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, + m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, + m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, + m68k_op_and_16_re_aw, m68k_op_and_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, + m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, + m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, + m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, + m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, + m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, + m68k_op_and_32_re_aw, m68k_op_and_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, + m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, + m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, + m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, + m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, + m68k_op_muls_16_aw, m68k_op_muls_16_al, m68k_op_muls_16_pcdi, m68k_op_muls_16_pcix, m68k_op_muls_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, + m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi7, + m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd7, + m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, + m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, + m68k_op_and_8_er_aw, m68k_op_and_8_er_al, m68k_op_and_8_er_pcdi, m68k_op_and_8_er_pcix, m68k_op_and_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, + m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, + m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, + m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, + m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, + m68k_op_and_16_er_aw, m68k_op_and_16_er_al, m68k_op_and_16_er_pcdi, m68k_op_and_16_er_pcix, m68k_op_and_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, + m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, + m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, + m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, + m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, + m68k_op_and_32_er_aw, m68k_op_and_32_er_al, m68k_op_and_32_er_pcdi, m68k_op_and_32_er_pcix, m68k_op_and_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, + m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, + m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, + m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, + m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, + m68k_op_mulu_16_aw, m68k_op_mulu_16_al, m68k_op_mulu_16_pcdi, m68k_op_mulu_16_pcix, m68k_op_mulu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, + m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm_ay7, + m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, + m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi7, + m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd7, + m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, + m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, + m68k_op_and_8_re_aw, m68k_op_and_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, + m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, + m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, + m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, + m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, + m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, + m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, + m68k_op_and_16_re_aw, m68k_op_and_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, + m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, + m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, + m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, + m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, + m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, + m68k_op_and_32_re_aw, m68k_op_and_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, + m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, + m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, + m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, + m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, + m68k_op_muls_16_aw, m68k_op_muls_16_al, m68k_op_muls_16_pcdi, m68k_op_muls_16_pcix, m68k_op_muls_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, + m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi7, + m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd7, + m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, + m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, + m68k_op_and_8_er_aw, m68k_op_and_8_er_al, m68k_op_and_8_er_pcdi, m68k_op_and_8_er_pcix, m68k_op_and_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, + m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, + m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, + m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, + m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, + m68k_op_and_16_er_aw, m68k_op_and_16_er_al, m68k_op_and_16_er_pcdi, m68k_op_and_16_er_pcix, m68k_op_and_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, + m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, + m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, + m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, + m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, + m68k_op_and_32_er_aw, m68k_op_and_32_er_al, m68k_op_and_32_er_pcdi, m68k_op_and_32_er_pcix, m68k_op_and_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, + m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, + m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, + m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, + m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, + m68k_op_mulu_16_aw, m68k_op_mulu_16_al, m68k_op_mulu_16_pcdi, m68k_op_mulu_16_pcix, m68k_op_mulu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, + m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm_ay7, + m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, + m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi7, + m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd7, + m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, + m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, + m68k_op_and_8_re_aw, m68k_op_and_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, + m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, + m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, + m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, + m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, + m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, + m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, + m68k_op_and_16_re_aw, m68k_op_and_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, + m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, + m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, + m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, + m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, + m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, + m68k_op_and_32_re_aw, m68k_op_and_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, + m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, + m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, + m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, + m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, + m68k_op_muls_16_aw, m68k_op_muls_16_al, m68k_op_muls_16_pcdi, m68k_op_muls_16_pcix, m68k_op_muls_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, + m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi7, + m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd7, + m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, + m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, + m68k_op_and_8_er_aw, m68k_op_and_8_er_al, m68k_op_and_8_er_pcdi, m68k_op_and_8_er_pcix, m68k_op_and_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, + m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, + m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, + m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, + m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, + m68k_op_and_16_er_aw, m68k_op_and_16_er_al, m68k_op_and_16_er_pcdi, m68k_op_and_16_er_pcix, m68k_op_and_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, + m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, + m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, + m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, + m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, + m68k_op_and_32_er_aw, m68k_op_and_32_er_al, m68k_op_and_32_er_pcdi, m68k_op_and_32_er_pcix, m68k_op_and_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, + m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, + m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, + m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, + m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, + m68k_op_mulu_16_aw, m68k_op_mulu_16_al, m68k_op_mulu_16_pcdi, m68k_op_mulu_16_pcix, m68k_op_mulu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, + m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm_ay7, + m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, + m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi7, + m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd7, + m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, + m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, + m68k_op_and_8_re_aw, m68k_op_and_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, + m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, + m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, + m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, + m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, + m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, + m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, + m68k_op_and_16_re_aw, m68k_op_and_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, + m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, + m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, + m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, + m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, + m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, + m68k_op_and_32_re_aw, m68k_op_and_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, + m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, + m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, + m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, + m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, + m68k_op_muls_16_aw, m68k_op_muls_16_al, m68k_op_muls_16_pcdi, m68k_op_muls_16_pcix, m68k_op_muls_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, + m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi7, + m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd7, + m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, + m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, + m68k_op_and_8_er_aw, m68k_op_and_8_er_al, m68k_op_and_8_er_pcdi, m68k_op_and_8_er_pcix, m68k_op_and_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, + m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, + m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, + m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, + m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, + m68k_op_and_16_er_aw, m68k_op_and_16_er_al, m68k_op_and_16_er_pcdi, m68k_op_and_16_er_pcix, m68k_op_and_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, + m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, + m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, + m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, + m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, + m68k_op_and_32_er_aw, m68k_op_and_32_er_al, m68k_op_and_32_er_pcdi, m68k_op_and_32_er_pcix, m68k_op_and_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, + m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, + m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, + m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, + m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, + m68k_op_mulu_16_aw, m68k_op_mulu_16_al, m68k_op_mulu_16_pcdi, m68k_op_mulu_16_pcix, m68k_op_mulu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, + m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm_ay7, + m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, + m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi7, + m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd7, + m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, + m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, + m68k_op_and_8_re_aw, m68k_op_and_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, + m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, + m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, + m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, + m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, + m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, + m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, + m68k_op_and_16_re_aw, m68k_op_and_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, + m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, + m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, + m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, + m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, + m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, + m68k_op_and_32_re_aw, m68k_op_and_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, + m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, + m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, + m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, + m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, + m68k_op_muls_16_aw, m68k_op_muls_16_al, m68k_op_muls_16_pcdi, m68k_op_muls_16_pcix, m68k_op_muls_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, + m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi7, + m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd7, + m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, + m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, + m68k_op_and_8_er_aw, m68k_op_and_8_er_al, m68k_op_and_8_er_pcdi, m68k_op_and_8_er_pcix, m68k_op_and_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, + m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, + m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, + m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, + m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, + m68k_op_and_16_er_aw, m68k_op_and_16_er_al, m68k_op_and_16_er_pcdi, m68k_op_and_16_er_pcix, m68k_op_and_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, + m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, + m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, + m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, + m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, + m68k_op_and_32_er_aw, m68k_op_and_32_er_al, m68k_op_and_32_er_pcdi, m68k_op_and_32_er_pcix, m68k_op_and_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, + m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, + m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, + m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, + m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, + m68k_op_mulu_16_aw, m68k_op_mulu_16_al, m68k_op_mulu_16_pcdi, m68k_op_mulu_16_pcix, m68k_op_mulu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, + m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm, m68k_op_abcd_8_mm_ay7, + m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, + m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi7, + m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd7, + m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, + m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, + m68k_op_and_8_re_aw, m68k_op_and_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, + m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, + m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, + m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, + m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, + m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, + m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, + m68k_op_and_16_re_aw, m68k_op_and_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, + m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, + m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, + m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, + m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, + m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, + m68k_op_and_32_re_aw, m68k_op_and_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, + m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, + m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, + m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, + m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, + m68k_op_muls_16_aw, m68k_op_muls_16_al, m68k_op_muls_16_pcdi, m68k_op_muls_16_pcix, m68k_op_muls_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, m68k_op_and_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, m68k_op_and_8_er_ai, + m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi, m68k_op_and_8_er_pi7, + m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd, m68k_op_and_8_er_pd7, + m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, m68k_op_and_8_er_di, + m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, m68k_op_and_8_er_ix, + m68k_op_and_8_er_aw, m68k_op_and_8_er_al, m68k_op_and_8_er_pcdi, m68k_op_and_8_er_pcix, m68k_op_and_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, m68k_op_and_16_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, m68k_op_and_16_er_ai, + m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, m68k_op_and_16_er_pi, + m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, m68k_op_and_16_er_pd, + m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, m68k_op_and_16_er_di, + m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, m68k_op_and_16_er_ix, + m68k_op_and_16_er_aw, m68k_op_and_16_er_al, m68k_op_and_16_er_pcdi, m68k_op_and_16_er_pcix, m68k_op_and_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, m68k_op_and_32_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, m68k_op_and_32_er_ai, + m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, m68k_op_and_32_er_pi, + m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, m68k_op_and_32_er_pd, + m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, m68k_op_and_32_er_di, + m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, m68k_op_and_32_er_ix, + m68k_op_and_32_er_aw, m68k_op_and_32_er_al, m68k_op_and_32_er_pcdi, m68k_op_and_32_er_pcix, m68k_op_and_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, m68k_op_mulu_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, m68k_op_mulu_16_ai, + m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, m68k_op_mulu_16_pi, + m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, m68k_op_mulu_16_pd, + m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, m68k_op_mulu_16_di, + m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, m68k_op_mulu_16_ix, + m68k_op_mulu_16_aw, m68k_op_mulu_16_al, m68k_op_mulu_16_pcdi, m68k_op_mulu_16_pcix, m68k_op_mulu_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, m68k_op_abcd_8_rr, + m68k_op_abcd_8_mm_ax7, m68k_op_abcd_8_mm_ax7, m68k_op_abcd_8_mm_ax7, m68k_op_abcd_8_mm_ax7, m68k_op_abcd_8_mm_ax7, m68k_op_abcd_8_mm_ax7, m68k_op_abcd_8_mm_ax7, m68k_op_abcd_8_mm_axy7, + m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, m68k_op_and_8_re_ai, + m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi, m68k_op_and_8_re_pi7, + m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd, m68k_op_and_8_re_pd7, + m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, m68k_op_and_8_re_di, + m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, m68k_op_and_8_re_ix, + m68k_op_and_8_re_aw, m68k_op_and_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, m68k_op_exg_32_dd, + m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, m68k_op_exg_32_aa, + m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, m68k_op_and_16_re_ai, + m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, m68k_op_and_16_re_pi, + m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, m68k_op_and_16_re_pd, + m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, m68k_op_and_16_re_di, + m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, m68k_op_and_16_re_ix, + m68k_op_and_16_re_aw, m68k_op_and_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, m68k_op_exg_32_da, + m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, m68k_op_and_32_re_ai, + m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, m68k_op_and_32_re_pi, + m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, m68k_op_and_32_re_pd, + m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, m68k_op_and_32_re_di, + m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, m68k_op_and_32_re_ix, + m68k_op_and_32_re_aw, m68k_op_and_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, m68k_op_muls_16_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, m68k_op_muls_16_ai, + m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, m68k_op_muls_16_pi, + m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, m68k_op_muls_16_pd, + m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, m68k_op_muls_16_di, + m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, m68k_op_muls_16_ix, + m68k_op_muls_16_aw, m68k_op_muls_16_al, m68k_op_muls_16_pcdi, m68k_op_muls_16_pcix, m68k_op_muls_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, + m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi7, + m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd7, + m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, + m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, + m68k_op_add_8_er_aw, m68k_op_add_8_er_al, m68k_op_add_8_er_pcdi, m68k_op_add_8_er_pcix, m68k_op_add_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, + m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, + m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, + m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, + m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, + m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, + m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, + m68k_op_add_16_er_aw, m68k_op_add_16_er_al, m68k_op_add_16_er_pcdi, m68k_op_add_16_er_pcix, m68k_op_add_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, + m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, + m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, + m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, + m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, + m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, + m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, + m68k_op_add_32_er_aw, m68k_op_add_32_er_al, m68k_op_add_32_er_pcdi, m68k_op_add_32_er_pcix, m68k_op_add_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, + m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, + m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, + m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, + m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, + m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, + m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, + m68k_op_adda_16_aw, m68k_op_adda_16_al, m68k_op_adda_16_pcdi, m68k_op_adda_16_pcix, m68k_op_adda_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, + m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm_ay7, + m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, + m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi7, + m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd7, + m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, + m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, + m68k_op_add_8_re_aw, m68k_op_add_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, + m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, + m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, + m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, + m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, + m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, + m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, + m68k_op_add_16_re_aw, m68k_op_add_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, + m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, + m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, + m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, + m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, + m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, + m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, + m68k_op_add_32_re_aw, m68k_op_add_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, + m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, + m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, + m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, + m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, + m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, + m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, + m68k_op_adda_32_aw, m68k_op_adda_32_al, m68k_op_adda_32_pcdi, m68k_op_adda_32_pcix, m68k_op_adda_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, + m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi7, + m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd7, + m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, + m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, + m68k_op_add_8_er_aw, m68k_op_add_8_er_al, m68k_op_add_8_er_pcdi, m68k_op_add_8_er_pcix, m68k_op_add_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, + m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, + m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, + m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, + m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, + m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, + m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, + m68k_op_add_16_er_aw, m68k_op_add_16_er_al, m68k_op_add_16_er_pcdi, m68k_op_add_16_er_pcix, m68k_op_add_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, + m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, + m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, + m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, + m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, + m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, + m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, + m68k_op_add_32_er_aw, m68k_op_add_32_er_al, m68k_op_add_32_er_pcdi, m68k_op_add_32_er_pcix, m68k_op_add_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, + m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, + m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, + m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, + m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, + m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, + m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, + m68k_op_adda_16_aw, m68k_op_adda_16_al, m68k_op_adda_16_pcdi, m68k_op_adda_16_pcix, m68k_op_adda_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, + m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm_ay7, + m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, + m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi7, + m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd7, + m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, + m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, + m68k_op_add_8_re_aw, m68k_op_add_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, + m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, + m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, + m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, + m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, + m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, + m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, + m68k_op_add_16_re_aw, m68k_op_add_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, + m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, + m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, + m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, + m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, + m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, + m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, + m68k_op_add_32_re_aw, m68k_op_add_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, + m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, + m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, + m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, + m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, + m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, + m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, + m68k_op_adda_32_aw, m68k_op_adda_32_al, m68k_op_adda_32_pcdi, m68k_op_adda_32_pcix, m68k_op_adda_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, + m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi7, + m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd7, + m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, + m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, + m68k_op_add_8_er_aw, m68k_op_add_8_er_al, m68k_op_add_8_er_pcdi, m68k_op_add_8_er_pcix, m68k_op_add_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, + m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, + m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, + m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, + m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, + m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, + m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, + m68k_op_add_16_er_aw, m68k_op_add_16_er_al, m68k_op_add_16_er_pcdi, m68k_op_add_16_er_pcix, m68k_op_add_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, + m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, + m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, + m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, + m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, + m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, + m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, + m68k_op_add_32_er_aw, m68k_op_add_32_er_al, m68k_op_add_32_er_pcdi, m68k_op_add_32_er_pcix, m68k_op_add_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, + m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, + m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, + m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, + m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, + m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, + m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, + m68k_op_adda_16_aw, m68k_op_adda_16_al, m68k_op_adda_16_pcdi, m68k_op_adda_16_pcix, m68k_op_adda_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, + m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm_ay7, + m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, + m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi7, + m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd7, + m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, + m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, + m68k_op_add_8_re_aw, m68k_op_add_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, + m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, + m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, + m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, + m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, + m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, + m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, + m68k_op_add_16_re_aw, m68k_op_add_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, + m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, + m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, + m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, + m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, + m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, + m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, + m68k_op_add_32_re_aw, m68k_op_add_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, + m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, + m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, + m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, + m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, + m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, + m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, + m68k_op_adda_32_aw, m68k_op_adda_32_al, m68k_op_adda_32_pcdi, m68k_op_adda_32_pcix, m68k_op_adda_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, + m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi7, + m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd7, + m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, + m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, + m68k_op_add_8_er_aw, m68k_op_add_8_er_al, m68k_op_add_8_er_pcdi, m68k_op_add_8_er_pcix, m68k_op_add_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, + m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, + m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, + m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, + m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, + m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, + m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, + m68k_op_add_16_er_aw, m68k_op_add_16_er_al, m68k_op_add_16_er_pcdi, m68k_op_add_16_er_pcix, m68k_op_add_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, + m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, + m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, + m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, + m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, + m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, + m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, + m68k_op_add_32_er_aw, m68k_op_add_32_er_al, m68k_op_add_32_er_pcdi, m68k_op_add_32_er_pcix, m68k_op_add_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, + m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, + m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, + m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, + m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, + m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, + m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, + m68k_op_adda_16_aw, m68k_op_adda_16_al, m68k_op_adda_16_pcdi, m68k_op_adda_16_pcix, m68k_op_adda_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, + m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm_ay7, + m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, + m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi7, + m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd7, + m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, + m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, + m68k_op_add_8_re_aw, m68k_op_add_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, + m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, + m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, + m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, + m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, + m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, + m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, + m68k_op_add_16_re_aw, m68k_op_add_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, + m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, + m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, + m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, + m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, + m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, + m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, + m68k_op_add_32_re_aw, m68k_op_add_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, + m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, + m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, + m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, + m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, + m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, + m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, + m68k_op_adda_32_aw, m68k_op_adda_32_al, m68k_op_adda_32_pcdi, m68k_op_adda_32_pcix, m68k_op_adda_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, + m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi7, + m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd7, + m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, + m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, + m68k_op_add_8_er_aw, m68k_op_add_8_er_al, m68k_op_add_8_er_pcdi, m68k_op_add_8_er_pcix, m68k_op_add_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, + m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, + m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, + m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, + m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, + m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, + m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, + m68k_op_add_16_er_aw, m68k_op_add_16_er_al, m68k_op_add_16_er_pcdi, m68k_op_add_16_er_pcix, m68k_op_add_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, + m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, + m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, + m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, + m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, + m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, + m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, + m68k_op_add_32_er_aw, m68k_op_add_32_er_al, m68k_op_add_32_er_pcdi, m68k_op_add_32_er_pcix, m68k_op_add_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, + m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, + m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, + m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, + m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, + m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, + m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, + m68k_op_adda_16_aw, m68k_op_adda_16_al, m68k_op_adda_16_pcdi, m68k_op_adda_16_pcix, m68k_op_adda_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, + m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm_ay7, + m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, + m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi7, + m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd7, + m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, + m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, + m68k_op_add_8_re_aw, m68k_op_add_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, + m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, + m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, + m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, + m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, + m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, + m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, + m68k_op_add_16_re_aw, m68k_op_add_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, + m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, + m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, + m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, + m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, + m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, + m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, + m68k_op_add_32_re_aw, m68k_op_add_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, + m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, + m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, + m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, + m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, + m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, + m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, + m68k_op_adda_32_aw, m68k_op_adda_32_al, m68k_op_adda_32_pcdi, m68k_op_adda_32_pcix, m68k_op_adda_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, + m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi7, + m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd7, + m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, + m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, + m68k_op_add_8_er_aw, m68k_op_add_8_er_al, m68k_op_add_8_er_pcdi, m68k_op_add_8_er_pcix, m68k_op_add_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, + m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, + m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, + m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, + m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, + m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, + m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, + m68k_op_add_16_er_aw, m68k_op_add_16_er_al, m68k_op_add_16_er_pcdi, m68k_op_add_16_er_pcix, m68k_op_add_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, + m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, + m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, + m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, + m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, + m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, + m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, + m68k_op_add_32_er_aw, m68k_op_add_32_er_al, m68k_op_add_32_er_pcdi, m68k_op_add_32_er_pcix, m68k_op_add_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, + m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, + m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, + m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, + m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, + m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, + m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, + m68k_op_adda_16_aw, m68k_op_adda_16_al, m68k_op_adda_16_pcdi, m68k_op_adda_16_pcix, m68k_op_adda_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, + m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm_ay7, + m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, + m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi7, + m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd7, + m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, + m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, + m68k_op_add_8_re_aw, m68k_op_add_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, + m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, + m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, + m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, + m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, + m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, + m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, + m68k_op_add_16_re_aw, m68k_op_add_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, + m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, + m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, + m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, + m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, + m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, + m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, + m68k_op_add_32_re_aw, m68k_op_add_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, + m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, + m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, + m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, + m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, + m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, + m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, + m68k_op_adda_32_aw, m68k_op_adda_32_al, m68k_op_adda_32_pcdi, m68k_op_adda_32_pcix, m68k_op_adda_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, + m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi7, + m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd7, + m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, + m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, + m68k_op_add_8_er_aw, m68k_op_add_8_er_al, m68k_op_add_8_er_pcdi, m68k_op_add_8_er_pcix, m68k_op_add_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, + m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, + m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, + m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, + m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, + m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, + m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, + m68k_op_add_16_er_aw, m68k_op_add_16_er_al, m68k_op_add_16_er_pcdi, m68k_op_add_16_er_pcix, m68k_op_add_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, + m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, + m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, + m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, + m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, + m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, + m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, + m68k_op_add_32_er_aw, m68k_op_add_32_er_al, m68k_op_add_32_er_pcdi, m68k_op_add_32_er_pcix, m68k_op_add_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, + m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, + m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, + m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, + m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, + m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, + m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, + m68k_op_adda_16_aw, m68k_op_adda_16_al, m68k_op_adda_16_pcdi, m68k_op_adda_16_pcix, m68k_op_adda_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, + m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm, m68k_op_addx_8_mm_ay7, + m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, + m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi7, + m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd7, + m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, + m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, + m68k_op_add_8_re_aw, m68k_op_add_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, + m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, + m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, + m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, + m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, + m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, + m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, + m68k_op_add_16_re_aw, m68k_op_add_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, + m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, + m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, + m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, + m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, + m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, + m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, + m68k_op_add_32_re_aw, m68k_op_add_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, + m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, + m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, + m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, + m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, + m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, + m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, + m68k_op_adda_32_aw, m68k_op_adda_32_al, m68k_op_adda_32_pcdi, m68k_op_adda_32_pcix, m68k_op_adda_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, m68k_op_add_8_er_d, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, m68k_op_add_8_er_ai, + m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi, m68k_op_add_8_er_pi7, + m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd, m68k_op_add_8_er_pd7, + m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, m68k_op_add_8_er_di, + m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, m68k_op_add_8_er_ix, + m68k_op_add_8_er_aw, m68k_op_add_8_er_al, m68k_op_add_8_er_pcdi, m68k_op_add_8_er_pcix, m68k_op_add_8_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, m68k_op_add_16_er_d, + m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, m68k_op_add_16_er_a, + m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, m68k_op_add_16_er_ai, + m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, m68k_op_add_16_er_pi, + m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, m68k_op_add_16_er_pd, + m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, m68k_op_add_16_er_di, + m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, m68k_op_add_16_er_ix, + m68k_op_add_16_er_aw, m68k_op_add_16_er_al, m68k_op_add_16_er_pcdi, m68k_op_add_16_er_pcix, m68k_op_add_16_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, m68k_op_add_32_er_d, + m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, m68k_op_add_32_er_a, + m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, m68k_op_add_32_er_ai, + m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, m68k_op_add_32_er_pi, + m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, m68k_op_add_32_er_pd, + m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, m68k_op_add_32_er_di, + m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, m68k_op_add_32_er_ix, + m68k_op_add_32_er_aw, m68k_op_add_32_er_al, m68k_op_add_32_er_pcdi, m68k_op_add_32_er_pcix, m68k_op_add_32_er_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, m68k_op_adda_16_d, + m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, m68k_op_adda_16_a, + m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, m68k_op_adda_16_ai, + m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, m68k_op_adda_16_pi, + m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, m68k_op_adda_16_pd, + m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, m68k_op_adda_16_di, + m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, m68k_op_adda_16_ix, + m68k_op_adda_16_aw, m68k_op_adda_16_al, m68k_op_adda_16_pcdi, m68k_op_adda_16_pcix, m68k_op_adda_16_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, m68k_op_addx_8_rr, + m68k_op_addx_8_mm_ax7, m68k_op_addx_8_mm_ax7, m68k_op_addx_8_mm_ax7, m68k_op_addx_8_mm_ax7, m68k_op_addx_8_mm_ax7, m68k_op_addx_8_mm_ax7, m68k_op_addx_8_mm_ax7, m68k_op_addx_8_mm_axy7, + m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, m68k_op_add_8_re_ai, + m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi, m68k_op_add_8_re_pi7, + m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd, m68k_op_add_8_re_pd7, + m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, m68k_op_add_8_re_di, + m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, m68k_op_add_8_re_ix, + m68k_op_add_8_re_aw, m68k_op_add_8_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, m68k_op_addx_16_rr, + m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, m68k_op_addx_16_mm, + m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, m68k_op_add_16_re_ai, + m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, m68k_op_add_16_re_pi, + m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, m68k_op_add_16_re_pd, + m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, m68k_op_add_16_re_di, + m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, m68k_op_add_16_re_ix, + m68k_op_add_16_re_aw, m68k_op_add_16_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, m68k_op_addx_32_rr, + m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, m68k_op_addx_32_mm, + m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, m68k_op_add_32_re_ai, + m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, m68k_op_add_32_re_pi, + m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, m68k_op_add_32_re_pd, + m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, m68k_op_add_32_re_di, + m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, m68k_op_add_32_re_ix, + m68k_op_add_32_re_aw, m68k_op_add_32_re_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, m68k_op_adda_32_d, + m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, m68k_op_adda_32_a, + m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, m68k_op_adda_32_ai, + m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, m68k_op_adda_32_pi, + m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, m68k_op_adda_32_pd, + m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, m68k_op_adda_32_di, + m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, m68k_op_adda_32_ix, + m68k_op_adda_32_aw, m68k_op_adda_32_al, m68k_op_adda_32_pcdi, m68k_op_adda_32_pcix, m68k_op_adda_32_i, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, + m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, + m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, + m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, + m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, + m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, + m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, + m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, + m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, + m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, + m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, + m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, + m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, + m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, + m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, + m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, + m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, + m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, + m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, + m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, + m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, + m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, + m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, + m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asr_16_ai, m68k_op_asr_16_ai, m68k_op_asr_16_ai, m68k_op_asr_16_ai, m68k_op_asr_16_ai, m68k_op_asr_16_ai, m68k_op_asr_16_ai, m68k_op_asr_16_ai, + m68k_op_asr_16_pi, m68k_op_asr_16_pi, m68k_op_asr_16_pi, m68k_op_asr_16_pi, m68k_op_asr_16_pi, m68k_op_asr_16_pi, m68k_op_asr_16_pi, m68k_op_asr_16_pi, + m68k_op_asr_16_pd, m68k_op_asr_16_pd, m68k_op_asr_16_pd, m68k_op_asr_16_pd, m68k_op_asr_16_pd, m68k_op_asr_16_pd, m68k_op_asr_16_pd, m68k_op_asr_16_pd, + m68k_op_asr_16_di, m68k_op_asr_16_di, m68k_op_asr_16_di, m68k_op_asr_16_di, m68k_op_asr_16_di, m68k_op_asr_16_di, m68k_op_asr_16_di, m68k_op_asr_16_di, + m68k_op_asr_16_ix, m68k_op_asr_16_ix, m68k_op_asr_16_ix, m68k_op_asr_16_ix, m68k_op_asr_16_ix, m68k_op_asr_16_ix, m68k_op_asr_16_ix, m68k_op_asr_16_ix, + m68k_op_asr_16_aw, m68k_op_asr_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, + m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, + m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, + m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, + m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, + m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, + m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, + m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, + m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, + m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, + m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, + m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, + m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, + m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, + m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, + m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, + m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, + m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, + m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, + m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, + m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, + m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, + m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, + m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asl_16_ai, m68k_op_asl_16_ai, m68k_op_asl_16_ai, m68k_op_asl_16_ai, m68k_op_asl_16_ai, m68k_op_asl_16_ai, m68k_op_asl_16_ai, m68k_op_asl_16_ai, + m68k_op_asl_16_pi, m68k_op_asl_16_pi, m68k_op_asl_16_pi, m68k_op_asl_16_pi, m68k_op_asl_16_pi, m68k_op_asl_16_pi, m68k_op_asl_16_pi, m68k_op_asl_16_pi, + m68k_op_asl_16_pd, m68k_op_asl_16_pd, m68k_op_asl_16_pd, m68k_op_asl_16_pd, m68k_op_asl_16_pd, m68k_op_asl_16_pd, m68k_op_asl_16_pd, m68k_op_asl_16_pd, + m68k_op_asl_16_di, m68k_op_asl_16_di, m68k_op_asl_16_di, m68k_op_asl_16_di, m68k_op_asl_16_di, m68k_op_asl_16_di, m68k_op_asl_16_di, m68k_op_asl_16_di, + m68k_op_asl_16_ix, m68k_op_asl_16_ix, m68k_op_asl_16_ix, m68k_op_asl_16_ix, m68k_op_asl_16_ix, m68k_op_asl_16_ix, m68k_op_asl_16_ix, m68k_op_asl_16_ix, + m68k_op_asl_16_aw, m68k_op_asl_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, + m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, + m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, + m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, + m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, + m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, + m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, + m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, + m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, + m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, + m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, + m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, + m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, + m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, + m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, + m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, + m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, + m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, + m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, + m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, + m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, + m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, + m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, + m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lsr_16_ai, m68k_op_lsr_16_ai, m68k_op_lsr_16_ai, m68k_op_lsr_16_ai, m68k_op_lsr_16_ai, m68k_op_lsr_16_ai, m68k_op_lsr_16_ai, m68k_op_lsr_16_ai, + m68k_op_lsr_16_pi, m68k_op_lsr_16_pi, m68k_op_lsr_16_pi, m68k_op_lsr_16_pi, m68k_op_lsr_16_pi, m68k_op_lsr_16_pi, m68k_op_lsr_16_pi, m68k_op_lsr_16_pi, + m68k_op_lsr_16_pd, m68k_op_lsr_16_pd, m68k_op_lsr_16_pd, m68k_op_lsr_16_pd, m68k_op_lsr_16_pd, m68k_op_lsr_16_pd, m68k_op_lsr_16_pd, m68k_op_lsr_16_pd, + m68k_op_lsr_16_di, m68k_op_lsr_16_di, m68k_op_lsr_16_di, m68k_op_lsr_16_di, m68k_op_lsr_16_di, m68k_op_lsr_16_di, m68k_op_lsr_16_di, m68k_op_lsr_16_di, + m68k_op_lsr_16_ix, m68k_op_lsr_16_ix, m68k_op_lsr_16_ix, m68k_op_lsr_16_ix, m68k_op_lsr_16_ix, m68k_op_lsr_16_ix, m68k_op_lsr_16_ix, m68k_op_lsr_16_ix, + m68k_op_lsr_16_aw, m68k_op_lsr_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, + m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, + m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, + m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, + m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, + m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, + m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, + m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, + m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, + m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, + m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, + m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, + m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, + m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, + m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, + m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, + m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, + m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, + m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, + m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, + m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, + m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, + m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, + m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_lsl_16_ai, m68k_op_lsl_16_ai, m68k_op_lsl_16_ai, m68k_op_lsl_16_ai, m68k_op_lsl_16_ai, m68k_op_lsl_16_ai, m68k_op_lsl_16_ai, m68k_op_lsl_16_ai, + m68k_op_lsl_16_pi, m68k_op_lsl_16_pi, m68k_op_lsl_16_pi, m68k_op_lsl_16_pi, m68k_op_lsl_16_pi, m68k_op_lsl_16_pi, m68k_op_lsl_16_pi, m68k_op_lsl_16_pi, + m68k_op_lsl_16_pd, m68k_op_lsl_16_pd, m68k_op_lsl_16_pd, m68k_op_lsl_16_pd, m68k_op_lsl_16_pd, m68k_op_lsl_16_pd, m68k_op_lsl_16_pd, m68k_op_lsl_16_pd, + m68k_op_lsl_16_di, m68k_op_lsl_16_di, m68k_op_lsl_16_di, m68k_op_lsl_16_di, m68k_op_lsl_16_di, m68k_op_lsl_16_di, m68k_op_lsl_16_di, m68k_op_lsl_16_di, + m68k_op_lsl_16_ix, m68k_op_lsl_16_ix, m68k_op_lsl_16_ix, m68k_op_lsl_16_ix, m68k_op_lsl_16_ix, m68k_op_lsl_16_ix, m68k_op_lsl_16_ix, m68k_op_lsl_16_ix, + m68k_op_lsl_16_aw, m68k_op_lsl_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, + m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, + m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, + m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, + m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, + m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, + m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, + m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, + m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, + m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, + m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, + m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, + m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, + m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, + m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, + m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, + m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, + m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, + m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, + m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, + m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, + m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, + m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, + m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_roxr_16_ai, m68k_op_roxr_16_ai, m68k_op_roxr_16_ai, m68k_op_roxr_16_ai, m68k_op_roxr_16_ai, m68k_op_roxr_16_ai, m68k_op_roxr_16_ai, m68k_op_roxr_16_ai, + m68k_op_roxr_16_pi, m68k_op_roxr_16_pi, m68k_op_roxr_16_pi, m68k_op_roxr_16_pi, m68k_op_roxr_16_pi, m68k_op_roxr_16_pi, m68k_op_roxr_16_pi, m68k_op_roxr_16_pi, + m68k_op_roxr_16_pd, m68k_op_roxr_16_pd, m68k_op_roxr_16_pd, m68k_op_roxr_16_pd, m68k_op_roxr_16_pd, m68k_op_roxr_16_pd, m68k_op_roxr_16_pd, m68k_op_roxr_16_pd, + m68k_op_roxr_16_di, m68k_op_roxr_16_di, m68k_op_roxr_16_di, m68k_op_roxr_16_di, m68k_op_roxr_16_di, m68k_op_roxr_16_di, m68k_op_roxr_16_di, m68k_op_roxr_16_di, + m68k_op_roxr_16_ix, m68k_op_roxr_16_ix, m68k_op_roxr_16_ix, m68k_op_roxr_16_ix, m68k_op_roxr_16_ix, m68k_op_roxr_16_ix, m68k_op_roxr_16_ix, m68k_op_roxr_16_ix, + m68k_op_roxr_16_aw, m68k_op_roxr_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, + m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, + m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, + m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, + m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, + m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, + m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, + m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, + m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, + m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, + m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, + m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, + m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, + m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, + m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, + m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, + m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, + m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, + m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, + m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, + m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, + m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, + m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, + m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_roxl_16_ai, m68k_op_roxl_16_ai, m68k_op_roxl_16_ai, m68k_op_roxl_16_ai, m68k_op_roxl_16_ai, m68k_op_roxl_16_ai, m68k_op_roxl_16_ai, m68k_op_roxl_16_ai, + m68k_op_roxl_16_pi, m68k_op_roxl_16_pi, m68k_op_roxl_16_pi, m68k_op_roxl_16_pi, m68k_op_roxl_16_pi, m68k_op_roxl_16_pi, m68k_op_roxl_16_pi, m68k_op_roxl_16_pi, + m68k_op_roxl_16_pd, m68k_op_roxl_16_pd, m68k_op_roxl_16_pd, m68k_op_roxl_16_pd, m68k_op_roxl_16_pd, m68k_op_roxl_16_pd, m68k_op_roxl_16_pd, m68k_op_roxl_16_pd, + m68k_op_roxl_16_di, m68k_op_roxl_16_di, m68k_op_roxl_16_di, m68k_op_roxl_16_di, m68k_op_roxl_16_di, m68k_op_roxl_16_di, m68k_op_roxl_16_di, m68k_op_roxl_16_di, + m68k_op_roxl_16_ix, m68k_op_roxl_16_ix, m68k_op_roxl_16_ix, m68k_op_roxl_16_ix, m68k_op_roxl_16_ix, m68k_op_roxl_16_ix, m68k_op_roxl_16_ix, m68k_op_roxl_16_ix, + m68k_op_roxl_16_aw, m68k_op_roxl_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, + m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, + m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, + m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, + m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, + m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, + m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, + m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, + m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, + m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, + m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, + m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, + m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, + m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, + m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, + m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, + m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, + m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, + m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, + m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, + m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, + m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, + m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, + m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_ror_16_ai, m68k_op_ror_16_ai, m68k_op_ror_16_ai, m68k_op_ror_16_ai, m68k_op_ror_16_ai, m68k_op_ror_16_ai, m68k_op_ror_16_ai, m68k_op_ror_16_ai, + m68k_op_ror_16_pi, m68k_op_ror_16_pi, m68k_op_ror_16_pi, m68k_op_ror_16_pi, m68k_op_ror_16_pi, m68k_op_ror_16_pi, m68k_op_ror_16_pi, m68k_op_ror_16_pi, + m68k_op_ror_16_pd, m68k_op_ror_16_pd, m68k_op_ror_16_pd, m68k_op_ror_16_pd, m68k_op_ror_16_pd, m68k_op_ror_16_pd, m68k_op_ror_16_pd, m68k_op_ror_16_pd, + m68k_op_ror_16_di, m68k_op_ror_16_di, m68k_op_ror_16_di, m68k_op_ror_16_di, m68k_op_ror_16_di, m68k_op_ror_16_di, m68k_op_ror_16_di, m68k_op_ror_16_di, + m68k_op_ror_16_ix, m68k_op_ror_16_ix, m68k_op_ror_16_ix, m68k_op_ror_16_ix, m68k_op_ror_16_ix, m68k_op_ror_16_ix, m68k_op_ror_16_ix, m68k_op_ror_16_ix, + m68k_op_ror_16_aw, m68k_op_ror_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, + m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, + m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, + m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, + m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, + m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, + m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, + m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, + m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, + m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, + m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, + m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, + m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, + m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, + m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, + m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, + m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, + m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, + m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, + m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, + m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, + m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, + m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, + m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_rol_16_ai, m68k_op_rol_16_ai, m68k_op_rol_16_ai, m68k_op_rol_16_ai, m68k_op_rol_16_ai, m68k_op_rol_16_ai, m68k_op_rol_16_ai, m68k_op_rol_16_ai, + m68k_op_rol_16_pi, m68k_op_rol_16_pi, m68k_op_rol_16_pi, m68k_op_rol_16_pi, m68k_op_rol_16_pi, m68k_op_rol_16_pi, m68k_op_rol_16_pi, m68k_op_rol_16_pi, + m68k_op_rol_16_pd, m68k_op_rol_16_pd, m68k_op_rol_16_pd, m68k_op_rol_16_pd, m68k_op_rol_16_pd, m68k_op_rol_16_pd, m68k_op_rol_16_pd, m68k_op_rol_16_pd, + m68k_op_rol_16_di, m68k_op_rol_16_di, m68k_op_rol_16_di, m68k_op_rol_16_di, m68k_op_rol_16_di, m68k_op_rol_16_di, m68k_op_rol_16_di, m68k_op_rol_16_di, + m68k_op_rol_16_ix, m68k_op_rol_16_ix, m68k_op_rol_16_ix, m68k_op_rol_16_ix, m68k_op_rol_16_ix, m68k_op_rol_16_ix, m68k_op_rol_16_ix, m68k_op_rol_16_ix, + m68k_op_rol_16_aw, m68k_op_rol_16_al, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, + m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, + m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, + m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, + m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, + m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, + m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, + m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, + m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, + m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, + m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, + m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, + m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, + m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, + m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, + m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, + m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, + m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, + m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, + m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, + m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, + m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, + m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, + m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, + m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, + m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, + m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, + m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, + m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, + m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, + m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, + m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, + m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, + m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, + m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, + m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, + m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, + m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, + m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, + m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, + m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, + m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, + m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, + m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, + m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, + m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, + m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, + m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, + m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, + m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, + m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, + m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, + m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, + m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, + m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, + m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, + m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, + m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, + m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, + m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, + m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, + m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, + m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, + m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, + m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, + m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, + m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, + m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, + m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, + m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, + m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, + m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, + m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, + m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, + m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, + m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, + m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, + m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, + m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, + m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, + m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, + m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, + m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, + m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, + m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, + m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, + m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, + m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, + m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, + m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, + m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, + m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, + m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, + m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, + m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, + m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, + m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, + m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, + m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, + m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, + m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, + m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, + m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, + m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, + m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, + m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, + m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, + m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, + m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, + m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, + m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, + m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, + m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, + m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, + m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, + m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, + m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, + m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, + m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, + m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, + m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, + m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, + m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, + m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, + m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, + m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, + m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, + m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, + m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, + m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, + m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, + m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, + m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, + m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, + m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, + m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, + m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, + m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, + m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, m68k_op_asr_8_s, + m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, m68k_op_lsr_8_s, + m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, m68k_op_roxr_8_s, + m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, m68k_op_ror_8_s, + m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, m68k_op_asr_8_r, + m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, m68k_op_lsr_8_r, + m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, m68k_op_roxr_8_r, + m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, m68k_op_ror_8_r, + m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, m68k_op_asr_16_s, + m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, m68k_op_lsr_16_s, + m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, m68k_op_roxr_16_s, + m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, m68k_op_ror_16_s, + m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, m68k_op_asr_16_r, + m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, m68k_op_lsr_16_r, + m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, m68k_op_roxr_16_r, + m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, m68k_op_ror_16_r, + m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, m68k_op_asr_32_s, + m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, m68k_op_lsr_32_s, + m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, m68k_op_roxr_32_s, + m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, m68k_op_ror_32_s, + m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, m68k_op_asr_32_r, + m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, m68k_op_lsr_32_r, + m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, m68k_op_roxr_32_r, + m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, m68k_op_ror_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, m68k_op_asl_8_s, + m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, m68k_op_lsl_8_s, + m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, m68k_op_roxl_8_s, + m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, m68k_op_rol_8_s, + m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, m68k_op_asl_8_r, + m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, m68k_op_lsl_8_r, + m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, m68k_op_roxl_8_r, + m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, m68k_op_rol_8_r, + m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, m68k_op_asl_16_s, + m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, m68k_op_lsl_16_s, + m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, m68k_op_roxl_16_s, + m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, m68k_op_rol_16_s, + m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, m68k_op_asl_16_r, + m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, m68k_op_lsl_16_r, + m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, m68k_op_roxl_16_r, + m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, m68k_op_rol_16_r, + m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, m68k_op_asl_32_s, + m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, m68k_op_lsl_32_s, + m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, m68k_op_roxl_32_s, + m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, m68k_op_rol_32_s, + m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, m68k_op_asl_32_r, + m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, m68k_op_lsl_32_r, + m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, m68k_op_roxl_32_r, + m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, m68k_op_rol_32_r, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, m68k_op_illegal, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, + m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, m68k_op_1111, +}; diff --git a/genplus-gx/core/m68k/m68kops.h b/genplus-gx/core/m68k/m68kops.h new file mode 100644 index 0000000000..fd5110e771 --- /dev/null +++ b/genplus-gx/core/m68k/m68kops.h @@ -0,0 +1,25461 @@ + +/* ======================================================================== */ +/* ============== CYCLE-ACCURATE DIV/MUL EXECUTION ======================== */ +/* ======================================================================== */ + +INLINE void UseDivuCycles(uint32 dst, uint32 src) +{ + int i; + + /* minimum cycle time */ + uint mcycles = 38 * MUL; + + /* 16-bit divisor */ + src <<= 16; + + /* 16-bit dividend */ + for (i=0; i<15; i++) + { + /* check if carry bit set */ + if ((sint32) dst < 0) + { + /* shift dividend and apply divisor */ + dst <<= 1; + dst -= src; + } + else + { + /* shift dividend and add two cycles */ + dst <<= 1; + mcycles += (2 * MUL); + + if (dst >= src) + { + /* apply divisor and remove one cycle */ + dst -= src; + mcycles -= 1 * MUL; + } + } + } + + USE_CYCLES(mcycles << 1); +} + +INLINE void UseDivsCycles(sint32 dst, sint16 src) +{ + /* minimum cycle time */ + uint mcycles = 6 * MUL; + + /* negative dividend */ + if (dst < 0) mcycles += 1 * MUL; + + if ((abs(dst) >> 16) < abs(src)) + { + int i; + + /* absolute quotient */ + uint32 quotient = abs(dst) / abs(src); + + /* add default cycle time */ + mcycles += (55 * MUL); + + /* positive divisor */ + if (src >= 0) + { + /* check dividend sign */ + if (dst >= 0) mcycles -= 1 * MUL; + else mcycles += 1 * MUL; + } + + /* check higher 15-bits of quotient */ + for (i=0; i<15; i++) + { + quotient >>= 1; + if (!(quotient & 1)) mcycles += 1 * MUL; + } + } + else + { + /* absolute overflow */ + mcycles += (2 * MUL); + } + + USE_CYCLES(mcycles << 1); +} + +INLINE void UseMuluCycles(uint16 src) +{ + /* minimum cycle time */ + uint mcycles = 38 * MUL; + + /* count number of bits set to 1 */ + while (src) + { + if (src & 1) mcycles += (2 * MUL); + src >>= 1; + } + + /* 38 + 2*N */ + USE_CYCLES(mcycles); +} + +INLINE void UseMulsCycles(sint16 src) +{ + /* minimum cycle time */ + uint mcycles = 38 * MUL; + + /* detect 01 or 10 patterns */ + sint32 tmp = src << 1; + tmp = (tmp ^ src) & 0xFFFF; + + /* count number of bits set to 1 */ + while (tmp) + { + if (tmp & 1) mcycles += (2 * MUL); + tmp >>= 1; + } + + /* 38 + 2*N */ + USE_CYCLES(mcycles); +} + + +/* ======================================================================== */ +/* ========================= INSTRUCTION HANDLERS ========================= */ +/* ======================================================================== */ + + +static void m68k_op_1010(void) +{ + m68ki_exception_1010(); +} + + +static void m68k_op_1111(void) +{ + m68ki_exception_1111(); +} + + +static void m68k_op_abcd_8_rr(void) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res += 6; + res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res -= 0xa0; + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; +} + + +static void m68k_op_abcd_8_mm_ax7(void) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res += 6; + res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res -= 0xa0; + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_abcd_8_mm_ay7(void) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res += 6; + res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res -= 0xa0; + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_abcd_8_mm_axy7(void) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res += 6; + res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res -= 0xa0; + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_abcd_8_mm(void) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); + + FLAG_V = ~res; /* Undefined V behavior */ + + if(res > 9) + res += 6; + res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); + FLAG_X = FLAG_C = (res > 0x99) << 8; + if(FLAG_C) + res -= 0xa0; + + FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_add_8_er_d(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_8(DY); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_ai(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_AI_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_pi(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PI_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_pi7(void) +{ + uint* r_dst = &DX; + uint src = OPER_A7_PI_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_pd(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PD_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_pd7(void) +{ + uint* r_dst = &DX; + uint src = OPER_A7_PD_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_di(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_DI_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_ix(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_IX_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_aw(void) +{ + uint* r_dst = &DX; + uint src = OPER_AW_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_al(void) +{ + uint* r_dst = &DX; + uint src = OPER_AL_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_pcdi(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCDI_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_pcix(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCIX_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_8_er_i(void) +{ + uint* r_dst = &DX; + uint src = OPER_I_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_d(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(DY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_a(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(AY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_ai(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_AI_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_pi(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PI_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_pd(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PD_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_di(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_DI_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_ix(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_IX_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_aw(void) +{ + uint* r_dst = &DX; + uint src = OPER_AW_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_al(void) +{ + uint* r_dst = &DX; + uint src = OPER_AL_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_pcdi(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCDI_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_pcix(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCIX_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_16_er_i(void) +{ + uint* r_dst = &DX; + uint src = OPER_I_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_add_32_er_d(void) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_32_er_a(void) +{ + uint* r_dst = &DX; + uint src = AY; + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_32_er_ai(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_AI_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_32_er_pi(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PI_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_32_er_pd(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PD_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_32_er_di(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_DI_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_32_er_ix(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_IX_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_32_er_aw(void) +{ + uint* r_dst = &DX; + uint src = OPER_AW_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_32_er_al(void) +{ + uint* r_dst = &DX; + uint src = OPER_AL_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_32_er_pcdi(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCDI_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_32_er_pcix(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCIX_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_32_er_i(void) +{ + uint* r_dst = &DX; + uint src = OPER_I_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_add_8_re_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_add_8_re_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_add_8_re_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_add_8_re_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_add_8_re_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_add_8_re_di(void) +{ + uint ea = EA_AY_DI_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_add_8_re_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_add_8_re_aw(void) +{ + uint ea = EA_AW_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_add_8_re_al(void) +{ + uint ea = EA_AL_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_add_16_re_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_add_16_re_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_add_16_re_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_add_16_re_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_add_16_re_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_add_16_re_aw(void) +{ + uint ea = EA_AW_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_add_16_re_al(void) +{ + uint ea = EA_AL_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_add_32_re_ai(void) +{ + uint ea = EA_AY_AI_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_add_32_re_pi(void) +{ + uint ea = EA_AY_PI_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_add_32_re_pd(void) +{ + uint ea = EA_AY_PD_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_add_32_re_di(void) +{ + uint ea = EA_AY_DI_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_add_32_re_ix(void) +{ + uint ea = EA_AY_IX_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_add_32_re_aw(void) +{ + uint ea = EA_AW_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_add_32_re_al(void) +{ + uint ea = EA_AL_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_adda_16_d(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + MAKE_INT_16(DY)); +} + + +static void m68k_op_adda_16_a(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + MAKE_INT_16(AY)); +} + + +static void m68k_op_adda_16_ai(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AY_AI_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +static void m68k_op_adda_16_pi(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AY_PI_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +static void m68k_op_adda_16_pd(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AY_PD_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +static void m68k_op_adda_16_di(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AY_DI_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +static void m68k_op_adda_16_ix(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AY_IX_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +static void m68k_op_adda_16_aw(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AW_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +static void m68k_op_adda_16_al(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AL_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +static void m68k_op_adda_16_pcdi(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_PCDI_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +static void m68k_op_adda_16_pcix(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_PCIX_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +static void m68k_op_adda_16_i(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_I_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + src); +} + + +static void m68k_op_adda_32_d(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + DY); +} + + +static void m68k_op_adda_32_a(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + AY); +} + + +static void m68k_op_adda_32_ai(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(OPER_AY_AI_32() + *r_dst); +} + + +static void m68k_op_adda_32_pi(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(OPER_AY_PI_32() + *r_dst); +} + + +static void m68k_op_adda_32_pd(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(OPER_AY_PD_32() + *r_dst); +} + + +static void m68k_op_adda_32_di(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(OPER_AY_DI_32() + *r_dst); +} + + +static void m68k_op_adda_32_ix(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(OPER_AY_IX_32() + *r_dst); +} + + +static void m68k_op_adda_32_aw(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(OPER_AW_32() + *r_dst); +} + + +static void m68k_op_adda_32_al(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(OPER_AL_32() + *r_dst); +} + + +static void m68k_op_adda_32_pcdi(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(OPER_PCDI_32() + *r_dst); +} + + +static void m68k_op_adda_32_pcix(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(OPER_PCIX_32() + *r_dst); +} + + +static void m68k_op_adda_32_i(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(OPER_I_32() + *r_dst); +} + + +static void m68k_op_addi_8_d(void) +{ + uint* r_dst = &DY; + uint src = OPER_I_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_addi_8_ai(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_AI_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addi_8_pi(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_PI_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addi_8_pi7(void) +{ + uint src = OPER_I_8(); + uint ea = EA_A7_PI_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addi_8_pd(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addi_8_pd7(void) +{ + uint src = OPER_I_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addi_8_di(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_DI_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addi_8_ix(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_IX_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addi_8_aw(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AW_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addi_8_al(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AL_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addi_16_d(void) +{ + uint* r_dst = &DY; + uint src = OPER_I_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_addi_16_ai(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_AI_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addi_16_pi(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_PI_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addi_16_pd(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_PD_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addi_16_di(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_DI_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addi_16_ix(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_IX_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addi_16_aw(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AW_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addi_16_al(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AL_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addi_32_d(void) +{ + uint* r_dst = &DY; + uint src = OPER_I_32(); + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_addi_32_ai(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_AI_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addi_32_pi(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_PI_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addi_32_pd(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_PD_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addi_32_di(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_DI_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addi_32_ix(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_IX_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addi_32_aw(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AW_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addi_32_al(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AL_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addq_8_d(void) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_addq_8_ai(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_AI_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addq_8_pi(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PI_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addq_8_pi7(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_A7_PI_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addq_8_pd(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addq_8_pd7(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addq_8_di(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_DI_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addq_8_ix(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_IX_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addq_8_aw(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AW_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addq_8_al(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AL_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst; + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_addq_16_d(void) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_addq_16_a(void) +{ + uint* r_dst = &AY; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + (((REG_IR >> 9) - 1) & 7) + 1); +} + + +static void m68k_op_addq_16_ai(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_AI_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addq_16_pi(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PI_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addq_16_pd(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PD_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addq_16_di(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_DI_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addq_16_ix(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_IX_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addq_16_aw(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AW_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addq_16_al(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AL_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst; + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_addq_32_d(void) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = *r_dst; + uint res = src + dst; + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_addq_32_a(void) +{ + uint* r_dst = &AY; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst + (((REG_IR >> 9) - 1) & 7) + 1); +} + + +static void m68k_op_addq_32_ai(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_AI_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addq_32_pi(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PI_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addq_32_pd(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PD_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addq_32_di(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_DI_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addq_32_ix(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_IX_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addq_32_aw(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AW_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addq_32_al(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AL_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst; + + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_addx_8_rr(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_8(DY); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; +} + + +static void m68k_op_addx_16_rr(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(DY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; +} + + +static void m68k_op_addx_32_rr(void) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + *r_dst = res; +} + + +static void m68k_op_addx_8_mm_ax7(void) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_addx_8_mm_ay7(void) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_addx_8_mm_axy7(void) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_addx_8_mm(void) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_V = VFLAG_ADD_8(src, dst, res); + FLAG_X = FLAG_C = CFLAG_8(res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_addx_16_mm(void) +{ + uint src = OPER_AY_PD_16(); + uint ea = EA_AX_PD_16(); + uint dst = m68ki_read_16(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_V = VFLAG_ADD_16(src, dst, res); + FLAG_X = FLAG_C = CFLAG_16(res); + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_addx_32_mm(void) +{ + uint src = OPER_AY_PD_32(); + uint ea = EA_AX_PD_32(); + uint dst = m68ki_read_32(ea); + uint res = src + dst + XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_ADD_32(src, dst, res); + FLAG_X = FLAG_C = CFLAG_ADD_32(src, dst, res); + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_and_8_er_d(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (DY | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_ai(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_AY_AI_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_pi(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_AY_PI_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_pi7(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_A7_PI_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_pd(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_AY_PD_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_pd7(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_A7_PD_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_di(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_AY_DI_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_ix(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_AY_IX_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_aw(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_AW_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_al(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_AL_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_pcdi(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_PCDI_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_pcix(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_PCIX_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_er_i(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DX &= (OPER_I_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_16_er_d(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (DY | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_16_er_ai(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (OPER_AY_AI_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_16_er_pi(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (OPER_AY_PI_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_16_er_pd(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (OPER_AY_PD_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_16_er_di(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (OPER_AY_DI_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_16_er_ix(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (OPER_AY_IX_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_16_er_aw(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (OPER_AW_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_16_er_al(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (OPER_AL_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_16_er_pcdi(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (OPER_PCDI_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_16_er_pcix(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (OPER_PCIX_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_16_er_i(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DX &= (OPER_I_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_32_er_d(void) +{ + FLAG_Z = DX &= DY; + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_32_er_ai(void) +{ + FLAG_Z = DX &= OPER_AY_AI_32(); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_32_er_pi(void) +{ + FLAG_Z = DX &= OPER_AY_PI_32(); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_32_er_pd(void) +{ + FLAG_Z = DX &= OPER_AY_PD_32(); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_32_er_di(void) +{ + FLAG_Z = DX &= OPER_AY_DI_32(); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_32_er_ix(void) +{ + FLAG_Z = DX &= OPER_AY_IX_32(); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_32_er_aw(void) +{ + FLAG_Z = DX &= OPER_AW_32(); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_32_er_al(void) +{ + FLAG_Z = DX &= OPER_AL_32(); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_32_er_pcdi(void) +{ + FLAG_Z = DX &= OPER_PCDI_32(); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_32_er_pcix(void) +{ + FLAG_Z = DX &= OPER_PCIX_32(); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_32_er_i(void) +{ + FLAG_Z = DX &= OPER_I_32(); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_and_8_re_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint res = DX & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_and_8_re_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint res = DX & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_and_8_re_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint res = DX & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_and_8_re_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint res = DX & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_and_8_re_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint res = DX & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_and_8_re_di(void) +{ + uint ea = EA_AY_DI_8(); + uint res = DX & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_and_8_re_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint res = DX & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_and_8_re_aw(void) +{ + uint ea = EA_AW_8(); + uint res = DX & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_and_8_re_al(void) +{ + uint ea = EA_AL_8(); + uint res = DX & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_and_16_re_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint res = DX & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_and_16_re_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint res = DX & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_and_16_re_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint res = DX & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_and_16_re_di(void) +{ + uint ea = EA_AY_DI_16(); + uint res = DX & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_and_16_re_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint res = DX & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_and_16_re_aw(void) +{ + uint ea = EA_AW_16(); + uint res = DX & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_and_16_re_al(void) +{ + uint ea = EA_AL_16(); + uint res = DX & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_and_32_re_ai(void) +{ + uint ea = EA_AY_AI_32(); + uint res = DX & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_and_32_re_pi(void) +{ + uint ea = EA_AY_PI_32(); + uint res = DX & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_and_32_re_pd(void) +{ + uint ea = EA_AY_PD_32(); + uint res = DX & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_and_32_re_di(void) +{ + uint ea = EA_AY_DI_32(); + uint res = DX & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_and_32_re_ix(void) +{ + uint ea = EA_AY_IX_32(); + uint res = DX & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_and_32_re_aw(void) +{ + uint ea = EA_AW_32(); + uint res = DX & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_and_32_re_al(void) +{ + uint ea = EA_AL_32(); + uint res = DX & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_andi_8_d(void) +{ + FLAG_Z = MASK_OUT_ABOVE_8(DY &= (OPER_I_8() | 0xffffff00)); + + FLAG_N = NFLAG_8(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_andi_8_ai(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_AI_8(); + uint res = src & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_andi_8_pi(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_PI_8(); + uint res = src & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_andi_8_pi7(void) +{ + uint src = OPER_I_8(); + uint ea = EA_A7_PI_8(); + uint res = src & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_andi_8_pd(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_PD_8(); + uint res = src & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_andi_8_pd7(void) +{ + uint src = OPER_I_8(); + uint ea = EA_A7_PD_8(); + uint res = src & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_andi_8_di(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_DI_8(); + uint res = src & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_andi_8_ix(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_IX_8(); + uint res = src & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_andi_8_aw(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AW_8(); + uint res = src & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_andi_8_al(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AL_8(); + uint res = src & m68ki_read_8(ea); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_andi_16_d(void) +{ + FLAG_Z = MASK_OUT_ABOVE_16(DY &= (OPER_I_16() | 0xffff0000)); + + FLAG_N = NFLAG_16(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_andi_16_ai(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_AI_16(); + uint res = src & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_andi_16_pi(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_PI_16(); + uint res = src & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_andi_16_pd(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_PD_16(); + uint res = src & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_andi_16_di(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_DI_16(); + uint res = src & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_andi_16_ix(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_IX_16(); + uint res = src & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_andi_16_aw(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AW_16(); + uint res = src & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_andi_16_al(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AL_16(); + uint res = src & m68ki_read_16(ea); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_andi_32_d(void) +{ + FLAG_Z = DY &= (OPER_I_32()); + + FLAG_N = NFLAG_32(FLAG_Z); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_andi_32_ai(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_AI_32(); + uint res = src & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_andi_32_pi(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_PI_32(); + uint res = src & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_andi_32_pd(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_PD_32(); + uint res = src & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_andi_32_di(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_DI_32(); + uint res = src & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_andi_32_ix(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_IX_32(); + uint res = src & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_andi_32_aw(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AW_32(); + uint res = src & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_andi_32_al(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AL_32(); + uint res = src & m68ki_read_32(ea); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_andi_16_toc(void) +{ + m68ki_set_ccr(m68ki_get_ccr() & OPER_I_16()); +} + + +static void m68k_op_andi_16_tos(void) +{ + if(FLAG_S) + { + uint src = OPER_I_16(); + m68ki_set_sr(m68ki_get_sr() & src); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_asr_8_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + if(GET_MSB_8(src)) + res |= m68ki_shift_8_table[shift]; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_X = FLAG_C = src << (9-shift); +} + + +static void m68k_op_asr_16_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + if(GET_MSB_16(src)) + res |= m68ki_shift_16_table[shift]; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_X = FLAG_C = src << (9-shift); +} + + +static void m68k_op_asr_32_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + if(GET_MSB_32(src)) + res |= m68ki_shift_32_table[shift]; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_X = FLAG_C = src << (9-shift); +} + + +static void m68k_op_asr_8_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = src >> shift; + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift < 8) + { + if(GET_MSB_8(src)) + res |= m68ki_shift_8_table[shift]; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_X = FLAG_C = src << (9-shift); + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + if(GET_MSB_8(src)) + { + *r_dst |= 0xff; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + FLAG_N = NFLAG_SET; + FLAG_Z = ZFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst &= 0xffffff00; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_8(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_asr_16_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = src >> shift; + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift < 16) + { + if(GET_MSB_16(src)) + res |= m68ki_shift_16_table[shift]; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_C = FLAG_X = (src >> (shift - 1))<<8; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + if(GET_MSB_16(src)) + { + *r_dst |= 0xffff; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + FLAG_N = NFLAG_SET; + FLAG_Z = ZFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst &= 0xffff0000; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_asr_32_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = *r_dst; + uint res = src >> shift; + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift < 32) + { + if(GET_MSB_32(src)) + res |= m68ki_shift_32_table[shift]; + + *r_dst = res; + + FLAG_C = FLAG_X = (src >> (shift - 1))<<8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + if(GET_MSB_32(src)) + { + *r_dst = 0xffffffff; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + FLAG_N = NFLAG_SET; + FLAG_Z = ZFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst = 0; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_asr_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + if(GET_MSB_16(src)) + res |= 0x8000; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = FLAG_X = src << 8; +} + + +static void m68k_op_asr_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + if(GET_MSB_16(src)) + res |= 0x8000; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = FLAG_X = src << 8; +} + + +static void m68k_op_asr_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + if(GET_MSB_16(src)) + res |= 0x8000; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = FLAG_X = src << 8; +} + + +static void m68k_op_asr_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + if(GET_MSB_16(src)) + res |= 0x8000; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = FLAG_X = src << 8; +} + + +static void m68k_op_asr_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + if(GET_MSB_16(src)) + res |= 0x8000; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = FLAG_X = src << 8; +} + + +static void m68k_op_asr_16_aw(void) +{ + uint ea = EA_AW_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + if(GET_MSB_16(src)) + res |= 0x8000; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = FLAG_X = src << 8; +} + + +static void m68k_op_asr_16_al(void) +{ + uint ea = EA_AL_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + if(GET_MSB_16(src)) + res |= 0x8000; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = FLAG_X = src << 8; +} + + +static void m68k_op_asl_8_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = MASK_OUT_ABOVE_8(src << shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_X = FLAG_C = src << shift; + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + src &= m68ki_shift_8_table[shift + 1]; + FLAG_V = (!(src == 0 || (src == m68ki_shift_8_table[shift + 1] && shift < 8)))<<7; +} + + +static void m68k_op_asl_16_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = MASK_OUT_ABOVE_16(src << shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> (8-shift); + src &= m68ki_shift_16_table[shift + 1]; + FLAG_V = (!(src == 0 || src == m68ki_shift_16_table[shift + 1]))<<7; +} + + +static void m68k_op_asl_32_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32(src << shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> (24-shift); + src &= m68ki_shift_32_table[shift + 1]; + FLAG_V = (!(src == 0 || src == m68ki_shift_32_table[shift + 1]))<<7; +} + + +static void m68k_op_asl_8_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = MASK_OUT_ABOVE_8(src << shift); + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift < 8) + { + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + FLAG_X = FLAG_C = src << shift; + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + src &= m68ki_shift_8_table[shift + 1]; + FLAG_V = (!(src == 0 || src == m68ki_shift_8_table[shift + 1]))<<7; + return; + } + + *r_dst &= 0xffffff00; + FLAG_X = FLAG_C = ((shift == 8 ? src & 1 : 0))<<8; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = (!(src == 0))<<7; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_8(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_asl_16_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = MASK_OUT_ABOVE_16(src << shift); + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift < 16) + { + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + FLAG_X = FLAG_C = (src << shift) >> 8; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + src &= m68ki_shift_16_table[shift + 1]; + FLAG_V = (!(src == 0 || src == m68ki_shift_16_table[shift + 1]))<<7; + return; + } + + *r_dst &= 0xffff0000; + FLAG_X = FLAG_C = ((shift == 16 ? src & 1 : 0))<<8; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = (!(src == 0))<<7; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_asl_32_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32(src << shift); + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift < 32) + { + *r_dst = res; + FLAG_X = FLAG_C = (src >> (32 - shift)) << 8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + src &= m68ki_shift_32_table[shift + 1]; + FLAG_V = (!(src == 0 || src == m68ki_shift_32_table[shift + 1]))<<7; + return; + } + + *r_dst = 0; + FLAG_X = FLAG_C = ((shift == 32 ? src & 1 : 0))<<8; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = (!(src == 0))<<7; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_asl_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + src &= 0xc000; + FLAG_V = (!(src == 0 || src == 0xc000))<<7; +} + + +static void m68k_op_asl_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + src &= 0xc000; + FLAG_V = (!(src == 0 || src == 0xc000))<<7; +} + + +static void m68k_op_asl_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + src &= 0xc000; + FLAG_V = (!(src == 0 || src == 0xc000))<<7; +} + + +static void m68k_op_asl_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + src &= 0xc000; + FLAG_V = (!(src == 0 || src == 0xc000))<<7; +} + + +static void m68k_op_asl_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + src &= 0xc000; + FLAG_V = (!(src == 0 || src == 0xc000))<<7; +} + + +static void m68k_op_asl_16_aw(void) +{ + uint ea = EA_AW_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + src &= 0xc000; + FLAG_V = (!(src == 0 || src == 0xc000))<<7; +} + + +static void m68k_op_asl_16_al(void) +{ + uint ea = EA_AL_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + src &= 0xc000; + FLAG_V = (!(src == 0 || src == 0xc000))<<7; +} + + +static void m68k_op_bhi_8(void) +{ + if(COND_HI()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bls_8(void) +{ + if(COND_LS()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bcc_8(void) +{ + if(COND_CC()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bcs_8(void) +{ + if(COND_CS()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bne_8(void) +{ + if(COND_NE()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_beq_8(void) +{ + if(COND_EQ()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bvc_8(void) +{ + if(COND_VC()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bvs_8(void) +{ + if(COND_VS()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bpl_8(void) +{ + if(COND_PL()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bmi_8(void) +{ + if(COND_MI()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bge_8(void) +{ + if(COND_GE()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_blt_8(void) +{ + if(COND_LT()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bgt_8(void) +{ + if(COND_GT()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_ble_8(void) +{ + if(COND_LE()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bhi_16(void) +{ + if(COND_HI()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_bls_16(void) +{ + if(COND_LS()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_bcc_16(void) +{ + if(COND_CC()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_bcs_16(void) +{ + if(COND_CS()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_bne_16(void) +{ + if(COND_NE()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_beq_16(void) +{ + if(COND_EQ()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_bvc_16(void) +{ + if(COND_VC()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_bvs_16(void) +{ + if(COND_VS()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_bpl_16(void) +{ + if(COND_PL()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_bmi_16(void) +{ + if(COND_MI()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_bge_16(void) +{ + if(COND_GE()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_blt_16(void) +{ + if(COND_LT()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_bgt_16(void) +{ + if(COND_GT()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_ble_16(void) +{ + if(COND_LE()) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + return; + } + REG_PC += 2; + USE_CYCLES(CYC_BCC_NOTAKE_W); +} + + +static void m68k_op_bhi_32(void) +{ + if(COND_HI()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bls_32(void) +{ + if(COND_LS()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bcc_32(void) +{ + if(COND_CC()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bcs_32(void) +{ + if(COND_CS()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bne_32(void) +{ + if(COND_NE()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_beq_32(void) +{ + if(COND_EQ()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bvc_32(void) +{ + if(COND_VC()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bvs_32(void) +{ + if(COND_VS()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bpl_32(void) +{ + if(COND_PL()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bmi_32(void) +{ + if(COND_MI()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bge_32(void) +{ + if(COND_GE()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_blt_32(void) +{ + if(COND_LT()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bgt_32(void) +{ + if(COND_GT()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_ble_32(void) +{ + if(COND_LE()) + { + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); + return; + } + USE_CYCLES(CYC_BCC_NOTAKE_B); +} + + +static void m68k_op_bchg_32_r_d(void) +{ + uint* r_dst = &DY; + uint mask = 1 << (DX & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst ^= mask; +} + + +static void m68k_op_bchg_8_r_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_r_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_r_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_r_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_r_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_r_di(void) +{ + uint ea = EA_AY_DI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_r_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_r_aw(void) +{ + uint ea = EA_AW_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_r_al(void) +{ + uint ea = EA_AL_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_32_s_d(void) +{ + uint* r_dst = &DY; + uint mask = 1 << (OPER_I_8() & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst ^= mask; +} + + +static void m68k_op_bchg_8_s_ai(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_AI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_s_pi(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_PI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_s_pi7(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_A7_PI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_s_pd(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_PD_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_s_pd7(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_A7_PD_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_s_di(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_DI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_s_ix(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_IX_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_s_aw(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AW_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bchg_8_s_al(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AL_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src ^ mask); +} + + +static void m68k_op_bclr_32_r_d(void) +{ + uint* r_dst = &DY; + uint mask = 1 << (DX & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst &= ~mask; +} + + +static void m68k_op_bclr_8_r_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_r_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_r_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_r_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_r_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_r_di(void) +{ + uint ea = EA_AY_DI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_r_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_r_aw(void) +{ + uint ea = EA_AW_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_r_al(void) +{ + uint ea = EA_AL_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_32_s_d(void) +{ + uint* r_dst = &DY; + uint mask = 1 << (OPER_I_8() & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst &= ~mask; +} + + +static void m68k_op_bclr_8_s_ai(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_AI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_s_pi(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_PI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_s_pi7(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_A7_PI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_s_pd(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_PD_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_s_pd7(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_A7_PD_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_s_di(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_DI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_s_ix(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_IX_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_s_aw(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AW_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bclr_8_s_al(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AL_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src & ~mask); +} + + +static void m68k_op_bra_8(void) +{ + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); +} + + +static void m68k_op_bra_16(void) +{ + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); +} + + +static void m68k_op_bra_32(void) +{ + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); +} + + +static void m68k_op_bset_32_r_d(void) +{ + uint* r_dst = &DY; + uint mask = 1 << (DX & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst |= mask; +} + + +static void m68k_op_bset_8_r_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_r_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_r_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_r_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_r_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_r_di(void) +{ + uint ea = EA_AY_DI_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_r_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_r_aw(void) +{ + uint ea = EA_AW_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_r_al(void) +{ + uint ea = EA_AL_8(); + uint src = m68ki_read_8(ea); + uint mask = 1 << (DX & 7); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_32_s_d(void) +{ + uint* r_dst = &DY; + uint mask = 1 << (OPER_I_8() & 0x1f); + + FLAG_Z = *r_dst & mask; + *r_dst |= mask; +} + + +static void m68k_op_bset_8_s_ai(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_AI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_s_pi(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_PI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_s_pi7(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_A7_PI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_s_pd(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_PD_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_s_pd7(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_A7_PD_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_s_di(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_DI_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_s_ix(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AY_IX_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_s_aw(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AW_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bset_8_s_al(void) +{ + uint mask = 1 << (OPER_I_8() & 7); + uint ea = EA_AL_8(); + uint src = m68ki_read_8(ea); + + FLAG_Z = src & mask; + m68ki_write_8(ea, src | mask); +} + + +static void m68k_op_bsr_8(void) +{ + m68ki_push_32(REG_PC); + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); +} + + +static void m68k_op_bsr_16(void) +{ + uint offset = OPER_I_16(); + m68ki_push_32(REG_PC); + REG_PC -= 2; + m68ki_branch_16(offset); +} + + +static void m68k_op_bsr_32(void) +{ + m68ki_push_32(REG_PC); + m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); +} + + +static void m68k_op_btst_32_r_d(void) +{ + FLAG_Z = DY & (1 << (DX & 0x1f)); +} + + +static void m68k_op_btst_8_r_ai(void) +{ + FLAG_Z = OPER_AY_AI_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_8_r_pi(void) +{ + FLAG_Z = OPER_AY_PI_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_8_r_pi7(void) +{ + FLAG_Z = OPER_A7_PI_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_8_r_pd(void) +{ + FLAG_Z = OPER_AY_PD_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_8_r_pd7(void) +{ + FLAG_Z = OPER_A7_PD_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_8_r_di(void) +{ + FLAG_Z = OPER_AY_DI_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_8_r_ix(void) +{ + FLAG_Z = OPER_AY_IX_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_8_r_aw(void) +{ + FLAG_Z = OPER_AW_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_8_r_al(void) +{ + FLAG_Z = OPER_AL_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_8_r_pcdi(void) +{ + FLAG_Z = OPER_PCDI_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_8_r_pcix(void) +{ + FLAG_Z = OPER_PCIX_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_8_r_i(void) +{ + FLAG_Z = OPER_I_8() & (1 << (DX & 7)); +} + + +static void m68k_op_btst_32_s_d(void) +{ + FLAG_Z = DY & (1 << (OPER_I_8() & 0x1f)); +} + + +static void m68k_op_btst_8_s_ai(void) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = OPER_AY_AI_8() & (1 << bit); +} + + +static void m68k_op_btst_8_s_pi(void) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = OPER_AY_PI_8() & (1 << bit); +} + + +static void m68k_op_btst_8_s_pi7(void) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = OPER_A7_PI_8() & (1 << bit); +} + + +static void m68k_op_btst_8_s_pd(void) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = OPER_AY_PD_8() & (1 << bit); +} + + +static void m68k_op_btst_8_s_pd7(void) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = OPER_A7_PD_8() & (1 << bit); +} + + +static void m68k_op_btst_8_s_di(void) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = OPER_AY_DI_8() & (1 << bit); +} + + +static void m68k_op_btst_8_s_ix(void) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = OPER_AY_IX_8() & (1 << bit); +} + + +static void m68k_op_btst_8_s_aw(void) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = OPER_AW_8() & (1 << bit); +} + + +static void m68k_op_btst_8_s_al(void) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = OPER_AL_8() & (1 << bit); +} + + +static void m68k_op_btst_8_s_pcdi(void) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = OPER_PCDI_8() & (1 << bit); +} + + +static void m68k_op_btst_8_s_pcix(void) +{ + uint bit = OPER_I_8() & 7; + + FLAG_Z = OPER_PCIX_8() & (1 << bit); +} + + +static void m68k_op_chk_16_d(void) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(DY); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +static void m68k_op_chk_16_ai(void) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(OPER_AY_AI_16()); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +static void m68k_op_chk_16_pi(void) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(OPER_AY_PI_16()); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +static void m68k_op_chk_16_pd(void) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(OPER_AY_PD_16()); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +static void m68k_op_chk_16_di(void) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(OPER_AY_DI_16()); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +static void m68k_op_chk_16_ix(void) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(OPER_AY_IX_16()); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +static void m68k_op_chk_16_aw(void) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(OPER_AW_16()); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +static void m68k_op_chk_16_al(void) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(OPER_AL_16()); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +static void m68k_op_chk_16_pcdi(void) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(OPER_PCDI_16()); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +static void m68k_op_chk_16_pcix(void) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(OPER_PCIX_16()); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +static void m68k_op_chk_16_i(void) +{ + sint src = MAKE_INT_16(DX); + sint bound = MAKE_INT_16(OPER_I_16()); + + FLAG_Z = ZFLAG_16(src); /* Undocumented */ + FLAG_V = VFLAG_CLEAR; /* Undocumented */ + FLAG_C = CFLAG_CLEAR; /* Undocumented */ + + if(src >= 0 && src <= bound) + { + return; + } + FLAG_N = (src < 0)<<7; + m68ki_exception_trap(EXCEPTION_CHK); +} + + +static void m68k_op_clr_8_d(void) +{ + DY &= 0xffffff00; + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_8_al(void) +{ + m68ki_write_8(EA_AL_8(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_16_d(void) +{ + DY &= 0xffff0000; + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_16_ai(void) +{ + m68ki_write_16(EA_AY_AI_16(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_16_pi(void) +{ + m68ki_write_16(EA_AY_PI_16(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_16_pd(void) +{ + m68ki_write_16(EA_AY_PD_16(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_16_di(void) +{ + m68ki_write_16(EA_AY_DI_16(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_16_ix(void) +{ + m68ki_write_16(EA_AY_IX_16(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_16_aw(void) +{ + m68ki_write_16(EA_AW_16(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_16_al(void) +{ + m68ki_write_16(EA_AL_16(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_32_d(void) +{ + DY = 0; + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_32_ai(void) +{ + m68ki_write_32(EA_AY_AI_32(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_32_pi(void) +{ + m68ki_write_32(EA_AY_PI_32(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_32_pd(void) +{ + m68ki_write_32(EA_AY_PD_32(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_32_di(void) +{ + m68ki_write_32(EA_AY_DI_32(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_32_ix(void) +{ + m68ki_write_32(EA_AY_IX_32(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_32_aw(void) +{ + m68ki_write_32(EA_AW_32(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_clr_32_al(void) +{ + m68ki_write_32(EA_AL_32(), 0); + + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; +} + + +static void m68k_op_cmp_8_d(void) +{ + uint src = MASK_OUT_ABOVE_8(DY); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_ai(void) +{ + uint src = OPER_AY_AI_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_pi(void) +{ + uint src = OPER_AY_PI_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_pi7(void) +{ + uint src = OPER_A7_PI_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_pd(void) +{ + uint src = OPER_AY_PD_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_pd7(void) +{ + uint src = OPER_A7_PD_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_di(void) +{ + uint src = OPER_AY_DI_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_ix(void) +{ + uint src = OPER_AY_IX_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_aw(void) +{ + uint src = OPER_AW_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_al(void) +{ + uint src = OPER_AL_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_pcdi(void) +{ + uint src = OPER_PCDI_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_pcix(void) +{ + uint src = OPER_PCIX_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_8_i(void) +{ + uint src = OPER_I_8(); + uint dst = MASK_OUT_ABOVE_8(DX); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmp_16_d(void) +{ + uint src = MASK_OUT_ABOVE_16(DY); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_16_a(void) +{ + uint src = MASK_OUT_ABOVE_16(AY); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_16_ai(void) +{ + uint src = OPER_AY_AI_16(); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_16_pi(void) +{ + uint src = OPER_AY_PI_16(); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_16_pd(void) +{ + uint src = OPER_AY_PD_16(); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_16_di(void) +{ + uint src = OPER_AY_DI_16(); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_16_ix(void) +{ + uint src = OPER_AY_IX_16(); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_16_aw(void) +{ + uint src = OPER_AW_16(); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_16_al(void) +{ + uint src = OPER_AL_16(); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_16_pcdi(void) +{ + uint src = OPER_PCDI_16(); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_16_pcix(void) +{ + uint src = OPER_PCIX_16(); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_16_i(void) +{ + uint src = OPER_I_16(); + uint dst = MASK_OUT_ABOVE_16(DX); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmp_32_d(void) +{ + uint src = DY; + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmp_32_a(void) +{ + uint src = AY; + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmp_32_ai(void) +{ + uint src = OPER_AY_AI_32(); + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmp_32_pi(void) +{ + uint src = OPER_AY_PI_32(); + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmp_32_pd(void) +{ + uint src = OPER_AY_PD_32(); + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmp_32_di(void) +{ + uint src = OPER_AY_DI_32(); + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmp_32_ix(void) +{ + uint src = OPER_AY_IX_32(); + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmp_32_aw(void) +{ + uint src = OPER_AW_32(); + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmp_32_al(void) +{ + uint src = OPER_AL_32(); + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmp_32_pcdi(void) +{ + uint src = OPER_PCDI_32(); + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmp_32_pcix(void) +{ + uint src = OPER_PCIX_32(); + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmp_32_i(void) +{ + uint src = OPER_I_32(); + uint dst = DX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_d(void) +{ + uint src = MAKE_INT_16(DY); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_a(void) +{ + uint src = MAKE_INT_16(AY); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_ai(void) +{ + uint src = MAKE_INT_16(OPER_AY_AI_16()); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_pi(void) +{ + uint src = MAKE_INT_16(OPER_AY_PI_16()); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_pd(void) +{ + uint src = MAKE_INT_16(OPER_AY_PD_16()); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_di(void) +{ + uint src = MAKE_INT_16(OPER_AY_DI_16()); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_ix(void) +{ + uint src = MAKE_INT_16(OPER_AY_IX_16()); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_aw(void) +{ + uint src = MAKE_INT_16(OPER_AW_16()); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_al(void) +{ + uint src = MAKE_INT_16(OPER_AL_16()); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_pcdi(void) +{ + uint src = MAKE_INT_16(OPER_PCDI_16()); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_pcix(void) +{ + uint src = MAKE_INT_16(OPER_PCIX_16()); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_16_i(void) +{ + uint src = MAKE_INT_16(OPER_I_16()); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_d(void) +{ + uint src = DY; + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_a(void) +{ + uint src = AY; + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_ai(void) +{ + uint src = OPER_AY_AI_32(); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_pi(void) +{ + uint src = OPER_AY_PI_32(); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_pd(void) +{ + uint src = OPER_AY_PD_32(); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_di(void) +{ + uint src = OPER_AY_DI_32(); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_ix(void) +{ + uint src = OPER_AY_IX_32(); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_aw(void) +{ + uint src = OPER_AW_32(); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_al(void) +{ + uint src = OPER_AL_32(); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_pcdi(void) +{ + uint src = OPER_PCDI_32(); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_pcix(void) +{ + uint src = OPER_PCIX_32(); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpa_32_i(void) +{ + uint src = OPER_I_32(); + uint dst = AX; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpi_8_d(void) +{ + uint src = OPER_I_8(); + uint dst = MASK_OUT_ABOVE_8(DY); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpi_8_ai(void) +{ + uint src = OPER_I_8(); + uint dst = OPER_AY_AI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpi_8_pi(void) +{ + uint src = OPER_I_8(); + uint dst = OPER_AY_PI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpi_8_pi7(void) +{ + uint src = OPER_I_8(); + uint dst = OPER_A7_PI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpi_8_pd(void) +{ + uint src = OPER_I_8(); + uint dst = OPER_AY_PD_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpi_8_pd7(void) +{ + uint src = OPER_I_8(); + uint dst = OPER_A7_PD_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpi_8_di(void) +{ + uint src = OPER_I_8(); + uint dst = OPER_AY_DI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpi_8_ix(void) +{ + uint src = OPER_I_8(); + uint dst = OPER_AY_IX_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpi_8_aw(void) +{ + uint src = OPER_I_8(); + uint dst = OPER_AW_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpi_8_al(void) +{ + uint src = OPER_I_8(); + uint dst = OPER_AL_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpi_16_d(void) +{ + uint src = OPER_I_16(); + uint dst = MASK_OUT_ABOVE_16(DY); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmpi_16_ai(void) +{ + uint src = OPER_I_16(); + uint dst = OPER_AY_AI_16(); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmpi_16_pi(void) +{ + uint src = OPER_I_16(); + uint dst = OPER_AY_PI_16(); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmpi_16_pd(void) +{ + uint src = OPER_I_16(); + uint dst = OPER_AY_PD_16(); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmpi_16_di(void) +{ + uint src = OPER_I_16(); + uint dst = OPER_AY_DI_16(); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmpi_16_ix(void) +{ + uint src = OPER_I_16(); + uint dst = OPER_AY_IX_16(); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmpi_16_aw(void) +{ + uint src = OPER_I_16(); + uint dst = OPER_AW_16(); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmpi_16_al(void) +{ + uint src = OPER_I_16(); + uint dst = OPER_AL_16(); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmpi_32_d(void) +{ + uint src = OPER_I_32(); + uint dst = DY; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpi_32_ai(void) +{ + uint src = OPER_I_32(); + uint dst = OPER_AY_AI_32(); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpi_32_pi(void) +{ + uint src = OPER_I_32(); + uint dst = OPER_AY_PI_32(); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpi_32_pd(void) +{ + uint src = OPER_I_32(); + uint dst = OPER_AY_PD_32(); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpi_32_di(void) +{ + uint src = OPER_I_32(); + uint dst = OPER_AY_DI_32(); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpi_32_ix(void) +{ + uint src = OPER_I_32(); + uint dst = OPER_AY_IX_32(); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpi_32_aw(void) +{ + uint src = OPER_I_32(); + uint dst = OPER_AW_32(); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpi_32_al(void) +{ + uint src = OPER_I_32(); + uint dst = OPER_AL_32(); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_cmpm_8_ax7(void) +{ + uint src = OPER_AY_PI_8(); + uint dst = OPER_A7_PI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpm_8_ay7(void) +{ + uint src = OPER_A7_PI_8(); + uint dst = OPER_AX_PI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpm_8_axy7(void) +{ + uint src = OPER_A7_PI_8(); + uint dst = OPER_A7_PI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpm_8(void) +{ + uint src = OPER_AY_PI_8(); + uint dst = OPER_AX_PI_8(); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_C = CFLAG_8(res); +} + + +static void m68k_op_cmpm_16(void) +{ + uint src = OPER_AY_PI_16(); + uint dst = OPER_AX_PI_16(); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_C = CFLAG_16(res); +} + + +static void m68k_op_cmpm_32(void) +{ + uint src = OPER_AY_PI_32(); + uint dst = OPER_AX_PI_32(); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_C = CFLAG_SUB_32(src, dst, res); +} + + +static void m68k_op_dbt_16(void) +{ + REG_PC += 2; +} + + +static void m68k_op_dbf_16(void) +{ + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); +} + + +static void m68k_op_dbhi_16(void) +{ + if(COND_NOT_HI()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dbls_16(void) +{ + if(COND_NOT_LS()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dbcc_16(void) +{ + if(COND_NOT_CC()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dbcs_16(void) +{ + if(COND_NOT_CS()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dbne_16(void) +{ + if(COND_NOT_NE()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dbeq_16(void) +{ + if(COND_NOT_EQ()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dbvc_16(void) +{ + if(COND_NOT_VC()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dbvs_16(void) +{ + if(COND_NOT_VS()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dbpl_16(void) +{ + if(COND_NOT_PL()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dbmi_16(void) +{ + if(COND_NOT_MI()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dbge_16(void) +{ + if(COND_NOT_GE()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dblt_16(void) +{ + if(COND_NOT_LT()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dbgt_16(void) +{ + if(COND_NOT_GT()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_dble_16(void) +{ + if(COND_NOT_LE()) + { + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(*r_dst - 1); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + if(res != 0xffff) + { + uint offset = OPER_I_16(); + REG_PC -= 2; + m68ki_branch_16(offset); + USE_CYCLES(CYC_DBCC_F_NOEXP); + + /* reset idle loop detection */ + m68ki_cpu.poll.detected = 0; + return; + } + REG_PC += 2; + USE_CYCLES(CYC_DBCC_F_EXP); + return; + } + REG_PC += 2; +} + + +static void m68k_op_divs_16_d(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(DY); + sint quotient; + sint remainder; + + if(src != 0) + { + UseDivsCycles(*r_dst,src); + + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divs_16_ai(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AY_AI_16()); + sint quotient; + sint remainder; + + if(src != 0) + { + UseDivsCycles(*r_dst,src); + + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divs_16_pi(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AY_PI_16()); + sint quotient; + sint remainder; + + if(src != 0) + { + UseDivsCycles(*r_dst,src); + + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divs_16_pd(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AY_PD_16()); + sint quotient; + sint remainder; + + if(src != 0) + { + UseDivsCycles(*r_dst,src); + + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divs_16_di(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AY_DI_16()); + sint quotient; + sint remainder; + + if(src != 0) + { + UseDivsCycles(*r_dst,src); + + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divs_16_ix(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AY_IX_16()); + sint quotient; + sint remainder; + + if(src != 0) + { + UseDivsCycles(*r_dst,src); + + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divs_16_aw(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AW_16()); + sint quotient; + sint remainder; + + if(src != 0) + { + UseDivsCycles(*r_dst,src); + + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divs_16_al(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AL_16()); + sint quotient; + sint remainder; + + if(src != 0) + { + UseDivsCycles(*r_dst,src); + + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divs_16_pcdi(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_PCDI_16()); + sint quotient; + sint remainder; + + if(src != 0) + { + UseDivsCycles(*r_dst,src); + + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divs_16_pcix(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_PCIX_16()); + sint quotient; + sint remainder; + + if(src != 0) + { + UseDivsCycles(*r_dst,src); + + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divs_16_i(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_I_16()); + sint quotient; + sint remainder; + + if(src != 0) + { + UseDivsCycles(*r_dst,src); + + if((uint32)*r_dst == 0x80000000 && src == -1) + { + FLAG_Z = 0; + FLAG_N = NFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = 0; + return; + } + + quotient = MAKE_INT_32(*r_dst) / src; + remainder = MAKE_INT_32(*r_dst) % src; + + if(quotient == MAKE_INT_16(quotient)) + { + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divu_16_d(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(DY); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + UseDivuCycles(*r_dst,src); + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + USE_CYCLES(7 * 10); + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divu_16_ai(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_AI_16(); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + UseDivuCycles(*r_dst,src); + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + USE_CYCLES(7 * 10); + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divu_16_pi(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PI_16(); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + UseDivuCycles(*r_dst,src); + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + USE_CYCLES(7 *10); + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divu_16_pd(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PD_16(); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + UseDivuCycles(*r_dst,src); + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + USE_CYCLES(7 * 10); + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divu_16_di(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_DI_16(); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + UseDivuCycles(*r_dst,src); + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + USE_CYCLES(7 * 10); + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divu_16_ix(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_IX_16(); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + UseDivuCycles(*r_dst,src); + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + USE_CYCLES(7 * 10); + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divu_16_aw(void) +{ + uint* r_dst = &DX; + uint src = OPER_AW_16(); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + UseDivuCycles(*r_dst,src); + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + USE_CYCLES(7 * 10); + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divu_16_al(void) +{ + uint* r_dst = &DX; + uint src = OPER_AL_16(); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + UseDivuCycles(*r_dst,src); + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + USE_CYCLES(7 * 10); + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divu_16_pcdi(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCDI_16(); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + UseDivuCycles(*r_dst,src); + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + USE_CYCLES(7 * 10); + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divu_16_pcix(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCIX_16(); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + UseDivuCycles(*r_dst,src); + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + USE_CYCLES(7 * 10); + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_divu_16_i(void) +{ + uint* r_dst = &DX; + uint src = OPER_I_16(); + + if(src != 0) + { + uint quotient = *r_dst / src; + uint remainder = *r_dst % src; + + if(quotient < 0x10000) + { + UseDivuCycles(*r_dst,src); + FLAG_Z = quotient; + FLAG_N = NFLAG_16(quotient); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); + return; + } + USE_CYCLES(7 * 10); + FLAG_V = VFLAG_SET; + FLAG_N = NFLAG_SET; /* undocumented behavior (fixes Blood Shot on Genesis) */ + FLAG_C = CFLAG_CLEAR; + return; + } + FLAG_C = CFLAG_CLEAR; + m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE); +} + + +static void m68k_op_eor_8_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY ^= MASK_OUT_ABOVE_8(DX)); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_8_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint res = MASK_OUT_ABOVE_8(DX ^ m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_8_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint res = MASK_OUT_ABOVE_8(DX ^ m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_8_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint res = MASK_OUT_ABOVE_8(DX ^ m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_8_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint res = MASK_OUT_ABOVE_8(DX ^ m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_8_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint res = MASK_OUT_ABOVE_8(DX ^ m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_8_di(void) +{ + uint ea = EA_AY_DI_8(); + uint res = MASK_OUT_ABOVE_8(DX ^ m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_8_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint res = MASK_OUT_ABOVE_8(DX ^ m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_8_aw(void) +{ + uint ea = EA_AW_8(); + uint res = MASK_OUT_ABOVE_8(DX ^ m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_8_al(void) +{ + uint ea = EA_AL_8(); + uint res = MASK_OUT_ABOVE_8(DX ^ m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_16_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY ^= MASK_OUT_ABOVE_16(DX)); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint res = MASK_OUT_ABOVE_16(DX ^ m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint res = MASK_OUT_ABOVE_16(DX ^ m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint res = MASK_OUT_ABOVE_16(DX ^ m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint res = MASK_OUT_ABOVE_16(DX ^ m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint res = MASK_OUT_ABOVE_16(DX ^ m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_16_aw(void) +{ + uint ea = EA_AW_16(); + uint res = MASK_OUT_ABOVE_16(DX ^ m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_16_al(void) +{ + uint ea = EA_AL_16(); + uint res = MASK_OUT_ABOVE_16(DX ^ m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_32_d(void) +{ + uint res = DY ^= DX; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_32_ai(void) +{ + uint ea = EA_AY_AI_32(); + uint res = DX ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_32_pi(void) +{ + uint ea = EA_AY_PI_32(); + uint res = DX ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_32_pd(void) +{ + uint ea = EA_AY_PD_32(); + uint res = DX ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_32_di(void) +{ + uint ea = EA_AY_DI_32(); + uint res = DX ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_32_ix(void) +{ + uint ea = EA_AY_IX_32(); + uint res = DX ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_32_aw(void) +{ + uint ea = EA_AW_32(); + uint res = DX ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eor_32_al(void) +{ + uint ea = EA_AL_32(); + uint res = DX ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_8_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY ^= OPER_I_8()); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_8_ai(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_AI_8(); + uint res = src ^ m68ki_read_8(ea); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_8_pi(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_PI_8(); + uint res = src ^ m68ki_read_8(ea); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_8_pi7(void) +{ + uint src = OPER_I_8(); + uint ea = EA_A7_PI_8(); + uint res = src ^ m68ki_read_8(ea); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_8_pd(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_PD_8(); + uint res = src ^ m68ki_read_8(ea); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_8_pd7(void) +{ + uint src = OPER_I_8(); + uint ea = EA_A7_PD_8(); + uint res = src ^ m68ki_read_8(ea); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_8_di(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_DI_8(); + uint res = src ^ m68ki_read_8(ea); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_8_ix(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_IX_8(); + uint res = src ^ m68ki_read_8(ea); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_8_aw(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AW_8(); + uint res = src ^ m68ki_read_8(ea); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_8_al(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AL_8(); + uint res = src ^ m68ki_read_8(ea); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_16_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY ^= OPER_I_16()); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_16_ai(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_AI_16(); + uint res = src ^ m68ki_read_16(ea); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_16_pi(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_PI_16(); + uint res = src ^ m68ki_read_16(ea); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_16_pd(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_PD_16(); + uint res = src ^ m68ki_read_16(ea); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_16_di(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_DI_16(); + uint res = src ^ m68ki_read_16(ea); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_16_ix(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_IX_16(); + uint res = src ^ m68ki_read_16(ea); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_16_aw(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AW_16(); + uint res = src ^ m68ki_read_16(ea); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_16_al(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AL_16(); + uint res = src ^ m68ki_read_16(ea); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_32_d(void) +{ + uint res = DY ^= OPER_I_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_32_ai(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_AI_32(); + uint res = src ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_32_pi(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_PI_32(); + uint res = src ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_32_pd(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_PD_32(); + uint res = src ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_32_di(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_DI_32(); + uint res = src ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_32_ix(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_IX_32(); + uint res = src ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_32_aw(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AW_32(); + uint res = src ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_32_al(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AL_32(); + uint res = src ^ m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_eori_16_toc(void) +{ + m68ki_set_ccr(m68ki_get_ccr() ^ OPER_I_16()); +} + + +static void m68k_op_eori_16_tos(void) +{ + if(FLAG_S) + { + uint src = OPER_I_16(); + m68ki_set_sr(m68ki_get_sr() ^ src); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_exg_32_dd(void) +{ + uint* reg_a = &DX; + uint* reg_b = &DY; + uint tmp = *reg_a; + *reg_a = *reg_b; + *reg_b = tmp; +} + + +static void m68k_op_exg_32_aa(void) +{ + uint* reg_a = &AX; + uint* reg_b = &AY; + uint tmp = *reg_a; + *reg_a = *reg_b; + *reg_b = tmp; +} + + +static void m68k_op_exg_32_da(void) +{ + uint* reg_a = &DX; + uint* reg_b = &AY; + uint tmp = *reg_a; + *reg_a = *reg_b; + *reg_b = tmp; +} + + +static void m68k_op_ext_16(void) +{ + uint* r_dst = &DY; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | MASK_OUT_ABOVE_8(*r_dst) | (GET_MSB_8(*r_dst) ? 0xff00 : 0); + + FLAG_N = NFLAG_16(*r_dst); + FLAG_Z = MASK_OUT_ABOVE_16(*r_dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_ext_32(void) +{ + uint* r_dst = &DY; + + *r_dst = MASK_OUT_ABOVE_16(*r_dst) | (GET_MSB_16(*r_dst) ? 0xffff0000 : 0); + + FLAG_N = NFLAG_32(*r_dst); + FLAG_Z = *r_dst; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_illegal(void) +{ + m68ki_exception_illegal(); +} + + +static void m68k_op_jmp_32_ai(void) +{ + m68ki_jump(EA_AY_AI_32()); +} + + +static void m68k_op_jmp_32_di(void) +{ + m68ki_jump(EA_AY_DI_32()); +} + + +static void m68k_op_jmp_32_ix(void) +{ + m68ki_jump(EA_AY_IX_32()); +} + + +static void m68k_op_jmp_32_aw(void) +{ + m68ki_jump(EA_AW_32()); +} + + +static void m68k_op_jmp_32_al(void) +{ + m68ki_jump(EA_AL_32()); +} + + +static void m68k_op_jmp_32_pcdi(void) +{ + m68ki_jump(EA_PCDI_32()); +} + + +static void m68k_op_jmp_32_pcix(void) +{ + m68ki_jump(EA_PCIX_32()); +} + + +static void m68k_op_jsr_32_ai(void) +{ + uint ea = EA_AY_AI_32(); + m68ki_push_32(REG_PC); + m68ki_jump(ea); +} + + +static void m68k_op_jsr_32_di(void) +{ + uint ea = EA_AY_DI_32(); + m68ki_push_32(REG_PC); + m68ki_jump(ea); +} + + +static void m68k_op_jsr_32_ix(void) +{ + uint ea = EA_AY_IX_32(); + m68ki_push_32(REG_PC); + m68ki_jump(ea); +} + + +static void m68k_op_jsr_32_aw(void) +{ + uint ea = EA_AW_32(); + m68ki_push_32(REG_PC); + m68ki_jump(ea); +} + + +static void m68k_op_jsr_32_al(void) +{ + uint ea = EA_AL_32(); + m68ki_push_32(REG_PC); + m68ki_jump(ea); +} + + +static void m68k_op_jsr_32_pcdi(void) +{ + uint ea = EA_PCDI_32(); + m68ki_push_32(REG_PC); + m68ki_jump(ea); +} + + +static void m68k_op_jsr_32_pcix(void) +{ + uint ea = EA_PCIX_32(); + m68ki_push_32(REG_PC); + m68ki_jump(ea); +} + + +static void m68k_op_lea_32_ai(void) +{ + AX = EA_AY_AI_32(); +} + + +static void m68k_op_lea_32_di(void) +{ + AX = EA_AY_DI_32(); +} + + +static void m68k_op_lea_32_ix(void) +{ + AX = EA_AY_IX_32(); +} + + +static void m68k_op_lea_32_aw(void) +{ + AX = EA_AW_32(); +} + + +static void m68k_op_lea_32_al(void) +{ + AX = EA_AL_32(); +} + + +static void m68k_op_lea_32_pcdi(void) +{ + AX = EA_PCDI_32(); +} + + +static void m68k_op_lea_32_pcix(void) +{ + AX = EA_PCIX_32(); +} + + +static void m68k_op_link_16_a7(void) +{ + REG_A[7] -= 4; + m68ki_write_32(REG_A[7], REG_A[7]); + REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16())); +} + + +static void m68k_op_link_16(void) +{ + uint* r_dst = &AY; + + m68ki_push_32(*r_dst); + *r_dst = REG_A[7]; + REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16())); +} + + +static void m68k_op_lsr_8_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_X = FLAG_C = src << (9-shift); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_16_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_X = FLAG_C = src << (9-shift); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_32_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = src >> shift; + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = res; + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_X = FLAG_C = src << (9-shift); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_8_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = src >> shift; + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift <= 8) + { + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + FLAG_X = FLAG_C = src << (9-shift); + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst &= 0xffffff00; + FLAG_X = XFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_8(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_16_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = src >> shift; + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift <= 16) + { + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + FLAG_C = FLAG_X = (src >> (shift - 1))<<8; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst &= 0xffff0000; + FLAG_X = XFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_32_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = *r_dst; + uint res = src >> shift; + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift < 32) + { + *r_dst = res; + FLAG_C = FLAG_X = (src >> (shift - 1))<<8; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst = 0; + FLAG_X = FLAG_C = (shift == 32 ? GET_MSB_32(src)>>23 : 0); + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_C = FLAG_X = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_C = FLAG_X = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_C = FLAG_X = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_C = FLAG_X = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_C = FLAG_X = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_16_aw(void) +{ + uint ea = EA_AW_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_C = FLAG_X = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsr_16_al(void) +{ + uint ea = EA_AL_16(); + uint src = m68ki_read_16(ea); + uint res = src >> 1; + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_CLEAR; + FLAG_Z = res; + FLAG_C = FLAG_X = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_8_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = MASK_OUT_ABOVE_8(src << shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src << shift; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_16_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = MASK_OUT_ABOVE_16(src << shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> (8-shift); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_32_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32(src << shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> (24-shift); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_8_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = MASK_OUT_ABOVE_8(src << shift); + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift <= 8) + { + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + FLAG_X = FLAG_C = src << shift; + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst &= 0xffffff00; + FLAG_X = XFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_8(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_16_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = MASK_OUT_ABOVE_16(src << shift); + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift <= 16) + { + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + FLAG_X = FLAG_C = (src << shift) >> 8; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst &= 0xffff0000; + FLAG_X = XFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_32_r(void) +{ + uint* r_dst = &DY; + uint shift = DX & 0x3f; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32(src << shift); + + if(shift != 0) + { + USE_CYCLES(shift * CYC_SHIFT); + + if(shift < 32) + { + *r_dst = res; + FLAG_X = FLAG_C = (src >> (32 - shift)) << 8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + *r_dst = 0; + FLAG_X = FLAG_C = ((shift == 32 ? src & 1 : 0))<<8; + FLAG_N = NFLAG_CLEAR; + FLAG_Z = ZFLAG_SET; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_16_aw(void) +{ + uint ea = EA_AW_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_lsl_16_al(void) +{ + uint ea = EA_AL_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(src << 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_X = FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_ai(void) +{ + uint res = OPER_AY_AI_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_pi(void) +{ + uint res = OPER_AY_PI_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_pi7(void) +{ + uint res = OPER_A7_PI_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_pd(void) +{ + uint res = OPER_AY_PD_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_pd7(void) +{ + uint res = OPER_A7_PD_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_di(void) +{ + uint res = OPER_AY_DI_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_ix(void) +{ + uint res = OPER_AY_IX_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_aw(void) +{ + uint res = OPER_AW_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_al(void) +{ + uint res = OPER_AL_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_pcdi(void) +{ + uint res = OPER_PCDI_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_pcix(void) +{ + uint res = OPER_PCIX_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_d_i(void) +{ + uint res = OPER_I_8(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_8_ai_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_ai(void) +{ + uint res = OPER_AY_AI_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_pi(void) +{ + uint res = OPER_AY_PI_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_pi7(void) +{ + uint res = OPER_A7_PI_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_pd(void) +{ + uint res = OPER_AY_PD_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_pd7(void) +{ + uint res = OPER_A7_PD_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_di(void) +{ + uint res = OPER_AY_DI_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_ix(void) +{ + uint res = OPER_AY_IX_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_aw(void) +{ + uint res = OPER_AW_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_al(void) +{ + uint res = OPER_AL_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_pcdi(void) +{ + uint res = OPER_PCDI_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_pcix(void) +{ + uint res = OPER_PCIX_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ai_i(void) +{ + uint res = OPER_I_8(); + uint ea = EA_AX_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_ai(void) +{ + uint res = OPER_AY_AI_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_pi(void) +{ + uint res = OPER_AY_PI_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_pi7(void) +{ + uint res = OPER_A7_PI_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_pd(void) +{ + uint res = OPER_AY_PD_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_pd7(void) +{ + uint res = OPER_A7_PD_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_di(void) +{ + uint res = OPER_AY_DI_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_ix(void) +{ + uint res = OPER_AY_IX_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_aw(void) +{ + uint res = OPER_AW_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_al(void) +{ + uint res = OPER_AL_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_pcdi(void) +{ + uint res = OPER_PCDI_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_pcix(void) +{ + uint res = OPER_PCIX_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi7_i(void) +{ + uint res = OPER_I_8(); + uint ea = EA_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_ai(void) +{ + uint res = OPER_AY_AI_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_pi(void) +{ + uint res = OPER_AY_PI_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_pi7(void) +{ + uint res = OPER_A7_PI_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_pd(void) +{ + uint res = OPER_AY_PD_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_pd7(void) +{ + uint res = OPER_A7_PD_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_di(void) +{ + uint res = OPER_AY_DI_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_ix(void) +{ + uint res = OPER_AY_IX_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_aw(void) +{ + uint res = OPER_AW_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_al(void) +{ + uint res = OPER_AL_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_pcdi(void) +{ + uint res = OPER_PCDI_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_pcix(void) +{ + uint res = OPER_PCIX_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pi_i(void) +{ + uint res = OPER_I_8(); + uint ea = EA_AX_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_ai(void) +{ + uint res = OPER_AY_AI_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_pi(void) +{ + uint res = OPER_AY_PI_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_pi7(void) +{ + uint res = OPER_A7_PI_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_pd(void) +{ + uint res = OPER_AY_PD_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_pd7(void) +{ + uint res = OPER_A7_PD_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_di(void) +{ + uint res = OPER_AY_DI_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_ix(void) +{ + uint res = OPER_AY_IX_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_aw(void) +{ + uint res = OPER_AW_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_al(void) +{ + uint res = OPER_AL_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_pcdi(void) +{ + uint res = OPER_PCDI_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_pcix(void) +{ + uint res = OPER_PCIX_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd7_i(void) +{ + uint res = OPER_I_8(); + uint ea = EA_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_ai(void) +{ + uint res = OPER_AY_AI_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_pi(void) +{ + uint res = OPER_AY_PI_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_pi7(void) +{ + uint res = OPER_A7_PI_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_pd(void) +{ + uint res = OPER_AY_PD_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_pd7(void) +{ + uint res = OPER_A7_PD_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_di(void) +{ + uint res = OPER_AY_DI_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_ix(void) +{ + uint res = OPER_AY_IX_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_aw(void) +{ + uint res = OPER_AW_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_al(void) +{ + uint res = OPER_AL_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_pcdi(void) +{ + uint res = OPER_PCDI_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_pcix(void) +{ + uint res = OPER_PCIX_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_pd_i(void) +{ + uint res = OPER_I_8(); + uint ea = EA_AX_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_ai(void) +{ + uint res = OPER_AY_AI_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_pi(void) +{ + uint res = OPER_AY_PI_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_pi7(void) +{ + uint res = OPER_A7_PI_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_pd(void) +{ + uint res = OPER_AY_PD_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_pd7(void) +{ + uint res = OPER_A7_PD_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_di(void) +{ + uint res = OPER_AY_DI_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_ix(void) +{ + uint res = OPER_AY_IX_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_aw(void) +{ + uint res = OPER_AW_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_al(void) +{ + uint res = OPER_AL_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_pcdi(void) +{ + uint res = OPER_PCDI_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_pcix(void) +{ + uint res = OPER_PCIX_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_di_i(void) +{ + uint res = OPER_I_8(); + uint ea = EA_AX_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_ai(void) +{ + uint res = OPER_AY_AI_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_pi(void) +{ + uint res = OPER_AY_PI_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_pi7(void) +{ + uint res = OPER_A7_PI_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_pd(void) +{ + uint res = OPER_AY_PD_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_pd7(void) +{ + uint res = OPER_A7_PD_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_di(void) +{ + uint res = OPER_AY_DI_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_ix(void) +{ + uint res = OPER_AY_IX_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_aw(void) +{ + uint res = OPER_AW_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_al(void) +{ + uint res = OPER_AL_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_pcdi(void) +{ + uint res = OPER_PCDI_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_pcix(void) +{ + uint res = OPER_PCIX_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_ix_i(void) +{ + uint res = OPER_I_8(); + uint ea = EA_AX_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_ai(void) +{ + uint res = OPER_AY_AI_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_pi(void) +{ + uint res = OPER_AY_PI_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_pi7(void) +{ + uint res = OPER_A7_PI_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_pd(void) +{ + uint res = OPER_AY_PD_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_pd7(void) +{ + uint res = OPER_A7_PD_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_di(void) +{ + uint res = OPER_AY_DI_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_ix(void) +{ + uint res = OPER_AY_IX_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_aw(void) +{ + uint res = OPER_AW_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_al(void) +{ + uint res = OPER_AL_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_pcdi(void) +{ + uint res = OPER_PCDI_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_pcix(void) +{ + uint res = OPER_PCIX_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_aw_i(void) +{ + uint res = OPER_I_8(); + uint ea = EA_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_ai(void) +{ + uint res = OPER_AY_AI_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_pi(void) +{ + uint res = OPER_AY_PI_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_pi7(void) +{ + uint res = OPER_A7_PI_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_pd(void) +{ + uint res = OPER_AY_PD_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_pd7(void) +{ + uint res = OPER_A7_PD_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_di(void) +{ + uint res = OPER_AY_DI_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_ix(void) +{ + uint res = OPER_AY_IX_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_aw(void) +{ + uint res = OPER_AW_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_al(void) +{ + uint res = OPER_AL_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_pcdi(void) +{ + uint res = OPER_PCDI_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_pcix(void) +{ + uint res = OPER_PCIX_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_8_al_i(void) +{ + uint res = OPER_I_8(); + uint ea = EA_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_move_16_d_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_d_a(void) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_d_ai(void) +{ + uint res = OPER_AY_AI_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_d_pi(void) +{ + uint res = OPER_AY_PI_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_d_pd(void) +{ + uint res = OPER_AY_PD_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_d_di(void) +{ + uint res = OPER_AY_DI_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_d_ix(void) +{ + uint res = OPER_AY_IX_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_d_aw(void) +{ + uint res = OPER_AW_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_d_al(void) +{ + uint res = OPER_AL_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_d_pcdi(void) +{ + uint res = OPER_PCDI_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_d_pcix(void) +{ + uint res = OPER_PCIX_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_d_i(void) +{ + uint res = OPER_I_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_16_ai_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ai_a(void) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ai_ai(void) +{ + uint res = OPER_AY_AI_16(); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ai_pi(void) +{ + uint res = OPER_AY_PI_16(); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ai_pd(void) +{ + uint res = OPER_AY_PD_16(); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ai_di(void) +{ + uint res = OPER_AY_DI_16(); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ai_ix(void) +{ + uint res = OPER_AY_IX_16(); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ai_aw(void) +{ + uint res = OPER_AW_16(); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ai_al(void) +{ + uint res = OPER_AL_16(); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ai_pcdi(void) +{ + uint res = OPER_PCDI_16(); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ai_pcix(void) +{ + uint res = OPER_PCIX_16(); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ai_i(void) +{ + uint res = OPER_I_16(); + uint ea = EA_AX_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_a(void) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_ai(void) +{ + uint res = OPER_AY_AI_16(); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_pi(void) +{ + uint res = OPER_AY_PI_16(); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_pd(void) +{ + uint res = OPER_AY_PD_16(); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_di(void) +{ + uint res = OPER_AY_DI_16(); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_ix(void) +{ + uint res = OPER_AY_IX_16(); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_aw(void) +{ + uint res = OPER_AW_16(); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_al(void) +{ + uint res = OPER_AL_16(); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_pcdi(void) +{ + uint res = OPER_PCDI_16(); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_pcix(void) +{ + uint res = OPER_PCIX_16(); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pi_i(void) +{ + uint res = OPER_I_16(); + uint ea = EA_AX_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_a(void) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_ai(void) +{ + uint res = OPER_AY_AI_16(); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_pi(void) +{ + uint res = OPER_AY_PI_16(); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_pd(void) +{ + uint res = OPER_AY_PD_16(); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_di(void) +{ + uint res = OPER_AY_DI_16(); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_ix(void) +{ + uint res = OPER_AY_IX_16(); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_aw(void) +{ + uint res = OPER_AW_16(); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_al(void) +{ + uint res = OPER_AL_16(); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_pcdi(void) +{ + uint res = OPER_PCDI_16(); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_pcix(void) +{ + uint res = OPER_PCIX_16(); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_pd_i(void) +{ + uint res = OPER_I_16(); + uint ea = EA_AX_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_a(void) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_ai(void) +{ + uint res = OPER_AY_AI_16(); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_pi(void) +{ + uint res = OPER_AY_PI_16(); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_pd(void) +{ + uint res = OPER_AY_PD_16(); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_di(void) +{ + uint res = OPER_AY_DI_16(); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_ix(void) +{ + uint res = OPER_AY_IX_16(); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_aw(void) +{ + uint res = OPER_AW_16(); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_al(void) +{ + uint res = OPER_AL_16(); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_pcdi(void) +{ + uint res = OPER_PCDI_16(); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_pcix(void) +{ + uint res = OPER_PCIX_16(); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_di_i(void) +{ + uint res = OPER_I_16(); + uint ea = EA_AX_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_a(void) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_ai(void) +{ + uint res = OPER_AY_AI_16(); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_pi(void) +{ + uint res = OPER_AY_PI_16(); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_pd(void) +{ + uint res = OPER_AY_PD_16(); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_di(void) +{ + uint res = OPER_AY_DI_16(); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_ix(void) +{ + uint res = OPER_AY_IX_16(); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_aw(void) +{ + uint res = OPER_AW_16(); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_al(void) +{ + uint res = OPER_AL_16(); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_pcdi(void) +{ + uint res = OPER_PCDI_16(); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_pcix(void) +{ + uint res = OPER_PCIX_16(); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_ix_i(void) +{ + uint res = OPER_I_16(); + uint ea = EA_AX_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_a(void) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_ai(void) +{ + uint res = OPER_AY_AI_16(); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_pi(void) +{ + uint res = OPER_AY_PI_16(); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_pd(void) +{ + uint res = OPER_AY_PD_16(); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_di(void) +{ + uint res = OPER_AY_DI_16(); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_ix(void) +{ + uint res = OPER_AY_IX_16(); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_aw(void) +{ + uint res = OPER_AW_16(); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_al(void) +{ + uint res = OPER_AL_16(); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_pcdi(void) +{ + uint res = OPER_PCDI_16(); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_pcix(void) +{ + uint res = OPER_PCIX_16(); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_aw_i(void) +{ + uint res = OPER_I_16(); + uint ea = EA_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_a(void) +{ + uint res = MASK_OUT_ABOVE_16(AY); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_ai(void) +{ + uint res = OPER_AY_AI_16(); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_pi(void) +{ + uint res = OPER_AY_PI_16(); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_pd(void) +{ + uint res = OPER_AY_PD_16(); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_di(void) +{ + uint res = OPER_AY_DI_16(); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_ix(void) +{ + uint res = OPER_AY_IX_16(); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_aw(void) +{ + uint res = OPER_AW_16(); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_al(void) +{ + uint res = OPER_AL_16(); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_pcdi(void) +{ + uint res = OPER_PCDI_16(); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_pcix(void) +{ + uint res = OPER_PCIX_16(); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_16_al_i(void) +{ + uint res = OPER_I_16(); + uint ea = EA_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_move_32_d_d(void) +{ + uint res = DY; + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_d_a(void) +{ + uint res = AY; + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_d_ai(void) +{ + uint res = OPER_AY_AI_32(); + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_d_pi(void) +{ + uint res = OPER_AY_PI_32(); + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_d_pd(void) +{ + uint res = OPER_AY_PD_32(); + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_d_di(void) +{ + uint res = OPER_AY_DI_32(); + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_d_ix(void) +{ + uint res = OPER_AY_IX_32(); + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_d_aw(void) +{ + uint res = OPER_AW_32(); + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_d_al(void) +{ + uint res = OPER_AL_32(); + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_d_pcdi(void) +{ + uint res = OPER_PCDI_32(); + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_d_pcix(void) +{ + uint res = OPER_PCIX_32(); + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_d_i(void) +{ + uint res = OPER_I_32(); + uint* r_dst = &DX; + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_move_32_ai_d(void) +{ + uint res = DY; + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ai_a(void) +{ + uint res = AY; + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ai_ai(void) +{ + uint res = OPER_AY_AI_32(); + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ai_pi(void) +{ + uint res = OPER_AY_PI_32(); + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ai_pd(void) +{ + uint res = OPER_AY_PD_32(); + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ai_di(void) +{ + uint res = OPER_AY_DI_32(); + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ai_ix(void) +{ + uint res = OPER_AY_IX_32(); + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ai_aw(void) +{ + uint res = OPER_AW_32(); + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ai_al(void) +{ + uint res = OPER_AL_32(); + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ai_pcdi(void) +{ + uint res = OPER_PCDI_32(); + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ai_pcix(void) +{ + uint res = OPER_PCIX_32(); + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ai_i(void) +{ + uint res = OPER_I_32(); + uint ea = EA_AX_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_d(void) +{ + uint res = DY; + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_a(void) +{ + uint res = AY; + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_ai(void) +{ + uint res = OPER_AY_AI_32(); + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_pi(void) +{ + uint res = OPER_AY_PI_32(); + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_pd(void) +{ + uint res = OPER_AY_PD_32(); + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_di(void) +{ + uint res = OPER_AY_DI_32(); + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_ix(void) +{ + uint res = OPER_AY_IX_32(); + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_aw(void) +{ + uint res = OPER_AW_32(); + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_al(void) +{ + uint res = OPER_AL_32(); + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_pcdi(void) +{ + uint res = OPER_PCDI_32(); + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_pcix(void) +{ + uint res = OPER_PCIX_32(); + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pi_i(void) +{ + uint res = OPER_I_32(); + uint ea = EA_AX_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_pd_d(void) +{ + uint res = DY; + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_pd_a(void) +{ + uint res = AY; + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_pd_ai(void) +{ + uint res = OPER_AY_AI_32(); + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_pd_pi(void) +{ + uint res = OPER_AY_PI_32(); + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_pd_pd(void) +{ + uint res = OPER_AY_PD_32(); + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_pd_di(void) +{ + uint res = OPER_AY_DI_32(); + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_pd_ix(void) +{ + uint res = OPER_AY_IX_32(); + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_pd_aw(void) +{ + uint res = OPER_AW_32(); + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_pd_al(void) +{ + uint res = OPER_AL_32(); + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_pd_pcdi(void) +{ + uint res = OPER_PCDI_32(); + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_pd_pcix(void) +{ + uint res = OPER_PCIX_32(); + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_pd_i(void) +{ + uint res = OPER_I_32(); + uint ea = EA_AX_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_16(ea+2, res & 0xFFFF ); + m68ki_write_16(ea, (res >> 16) & 0xFFFF ); +} + + +static void m68k_op_move_32_di_d(void) +{ + uint res = DY; + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_di_a(void) +{ + uint res = AY; + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_di_ai(void) +{ + uint res = OPER_AY_AI_32(); + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_di_pi(void) +{ + uint res = OPER_AY_PI_32(); + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_di_pd(void) +{ + uint res = OPER_AY_PD_32(); + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_di_di(void) +{ + uint res = OPER_AY_DI_32(); + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_di_ix(void) +{ + uint res = OPER_AY_IX_32(); + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_di_aw(void) +{ + uint res = OPER_AW_32(); + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_di_al(void) +{ + uint res = OPER_AL_32(); + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_di_pcdi(void) +{ + uint res = OPER_PCDI_32(); + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_di_pcix(void) +{ + uint res = OPER_PCIX_32(); + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_di_i(void) +{ + uint res = OPER_I_32(); + uint ea = EA_AX_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_d(void) +{ + uint res = DY; + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_a(void) +{ + uint res = AY; + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_ai(void) +{ + uint res = OPER_AY_AI_32(); + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_pi(void) +{ + uint res = OPER_AY_PI_32(); + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_pd(void) +{ + uint res = OPER_AY_PD_32(); + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_di(void) +{ + uint res = OPER_AY_DI_32(); + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_ix(void) +{ + uint res = OPER_AY_IX_32(); + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_aw(void) +{ + uint res = OPER_AW_32(); + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_al(void) +{ + uint res = OPER_AL_32(); + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_pcdi(void) +{ + uint res = OPER_PCDI_32(); + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_pcix(void) +{ + uint res = OPER_PCIX_32(); + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_ix_i(void) +{ + uint res = OPER_I_32(); + uint ea = EA_AX_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_d(void) +{ + uint res = DY; + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_a(void) +{ + uint res = AY; + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_ai(void) +{ + uint res = OPER_AY_AI_32(); + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_pi(void) +{ + uint res = OPER_AY_PI_32(); + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_pd(void) +{ + uint res = OPER_AY_PD_32(); + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_di(void) +{ + uint res = OPER_AY_DI_32(); + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_ix(void) +{ + uint res = OPER_AY_IX_32(); + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_aw(void) +{ + uint res = OPER_AW_32(); + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_al(void) +{ + uint res = OPER_AL_32(); + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_pcdi(void) +{ + uint res = OPER_PCDI_32(); + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_pcix(void) +{ + uint res = OPER_PCIX_32(); + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_aw_i(void) +{ + uint res = OPER_I_32(); + uint ea = EA_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_d(void) +{ + uint res = DY; + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_a(void) +{ + uint res = AY; + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_ai(void) +{ + uint res = OPER_AY_AI_32(); + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_pi(void) +{ + uint res = OPER_AY_PI_32(); + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_pd(void) +{ + uint res = OPER_AY_PD_32(); + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_di(void) +{ + uint res = OPER_AY_DI_32(); + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_ix(void) +{ + uint res = OPER_AY_IX_32(); + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_aw(void) +{ + uint res = OPER_AW_32(); + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_al(void) +{ + uint res = OPER_AL_32(); + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_pcdi(void) +{ + uint res = OPER_PCDI_32(); + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_pcix(void) +{ + uint res = OPER_PCIX_32(); + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_move_32_al_i(void) +{ + uint res = OPER_I_32(); + uint ea = EA_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_movea_16_d(void) +{ + AX = MAKE_INT_16(DY); +} + + +static void m68k_op_movea_16_a(void) +{ + AX = MAKE_INT_16(AY); +} + + +static void m68k_op_movea_16_ai(void) +{ + AX = MAKE_INT_16(OPER_AY_AI_16()); +} + + +static void m68k_op_movea_16_pi(void) +{ + AX = MAKE_INT_16(OPER_AY_PI_16()); +} + + +static void m68k_op_movea_16_pd(void) +{ + AX = MAKE_INT_16(OPER_AY_PD_16()); +} + + +static void m68k_op_movea_16_di(void) +{ + AX = MAKE_INT_16(OPER_AY_DI_16()); +} + + +static void m68k_op_movea_16_ix(void) +{ + AX = MAKE_INT_16(OPER_AY_IX_16()); +} + + +static void m68k_op_movea_16_aw(void) +{ + AX = MAKE_INT_16(OPER_AW_16()); +} + + +static void m68k_op_movea_16_al(void) +{ + AX = MAKE_INT_16(OPER_AL_16()); +} + + +static void m68k_op_movea_16_pcdi(void) +{ + AX = MAKE_INT_16(OPER_PCDI_16()); +} + + +static void m68k_op_movea_16_pcix(void) +{ + AX = MAKE_INT_16(OPER_PCIX_16()); +} + + +static void m68k_op_movea_16_i(void) +{ + AX = MAKE_INT_16(OPER_I_16()); +} + + +static void m68k_op_movea_32_d(void) +{ + AX = DY; +} + + +static void m68k_op_movea_32_a(void) +{ + AX = AY; +} + + +static void m68k_op_movea_32_ai(void) +{ + AX = OPER_AY_AI_32(); +} + + +static void m68k_op_movea_32_pi(void) +{ + AX = OPER_AY_PI_32(); +} + + +static void m68k_op_movea_32_pd(void) +{ + AX = OPER_AY_PD_32(); +} + + +static void m68k_op_movea_32_di(void) +{ + AX = OPER_AY_DI_32(); +} + + +static void m68k_op_movea_32_ix(void) +{ + AX = OPER_AY_IX_32(); +} + + +static void m68k_op_movea_32_aw(void) +{ + AX = OPER_AW_32(); +} + + +static void m68k_op_movea_32_al(void) +{ + AX = OPER_AL_32(); +} + + +static void m68k_op_movea_32_pcdi(void) +{ + AX = OPER_PCDI_32(); +} + + +static void m68k_op_movea_32_pcix(void) +{ + AX = OPER_PCIX_32(); +} + + +static void m68k_op_movea_32_i(void) +{ + AX = OPER_I_32(); +} + +static void m68k_op_move_16_toc_d(void) +{ + m68ki_set_ccr(DY); +} + + +static void m68k_op_move_16_toc_ai(void) +{ + m68ki_set_ccr(OPER_AY_AI_16()); +} + + +static void m68k_op_move_16_toc_pi(void) +{ + m68ki_set_ccr(OPER_AY_PI_16()); +} + + +static void m68k_op_move_16_toc_pd(void) +{ + m68ki_set_ccr(OPER_AY_PD_16()); +} + + +static void m68k_op_move_16_toc_di(void) +{ + m68ki_set_ccr(OPER_AY_DI_16()); +} + + +static void m68k_op_move_16_toc_ix(void) +{ + m68ki_set_ccr(OPER_AY_IX_16()); +} + + +static void m68k_op_move_16_toc_aw(void) +{ + m68ki_set_ccr(OPER_AW_16()); +} + + +static void m68k_op_move_16_toc_al(void) +{ + m68ki_set_ccr(OPER_AL_16()); +} + + +static void m68k_op_move_16_toc_pcdi(void) +{ + m68ki_set_ccr(OPER_PCDI_16()); +} + + +static void m68k_op_move_16_toc_pcix(void) +{ + m68ki_set_ccr(OPER_PCIX_16()); +} + + +static void m68k_op_move_16_toc_i(void) +{ + m68ki_set_ccr(OPER_I_16()); +} + + +static void m68k_op_move_16_frs_d(void) +{ + DY = MASK_OUT_BELOW_16(DY) | m68ki_get_sr(); +} + + +static void m68k_op_move_16_frs_ai(void) +{ + uint ea = EA_AY_AI_16(); + m68ki_write_16(ea, m68ki_get_sr()); +} + + +static void m68k_op_move_16_frs_pi(void) +{ + uint ea = EA_AY_PI_16(); + m68ki_write_16(ea, m68ki_get_sr()); +} + + +static void m68k_op_move_16_frs_pd(void) +{ + uint ea = EA_AY_PD_16(); + m68ki_write_16(ea, m68ki_get_sr()); +} + + +static void m68k_op_move_16_frs_di(void) +{ + uint ea = EA_AY_DI_16(); + m68ki_write_16(ea, m68ki_get_sr()); +} + + +static void m68k_op_move_16_frs_ix(void) +{ + uint ea = EA_AY_IX_16(); + m68ki_write_16(ea, m68ki_get_sr()); +} + + +static void m68k_op_move_16_frs_aw(void) +{ + uint ea = EA_AW_16(); + m68ki_write_16(ea, m68ki_get_sr()); +} + + +static void m68k_op_move_16_frs_al(void) +{ + uint ea = EA_AL_16(); + m68ki_write_16(ea, m68ki_get_sr()); +} + + +static void m68k_op_move_16_tos_d(void) +{ + if(FLAG_S) + { + m68ki_set_sr(DY); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_16_tos_ai(void) +{ + if(FLAG_S) + { + uint new_sr = OPER_AY_AI_16(); + m68ki_set_sr(new_sr); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_16_tos_pi(void) +{ + if(FLAG_S) + { + uint new_sr = OPER_AY_PI_16(); + m68ki_set_sr(new_sr); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_16_tos_pd(void) +{ + if(FLAG_S) + { + uint new_sr = OPER_AY_PD_16(); + m68ki_set_sr(new_sr); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_16_tos_di(void) +{ + if(FLAG_S) + { + uint new_sr = OPER_AY_DI_16(); + m68ki_set_sr(new_sr); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_16_tos_ix(void) +{ + if(FLAG_S) + { + uint new_sr = OPER_AY_IX_16(); + m68ki_set_sr(new_sr); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_16_tos_aw(void) +{ + if(FLAG_S) + { + uint new_sr = OPER_AW_16(); + m68ki_set_sr(new_sr); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_16_tos_al(void) +{ + if(FLAG_S) + { + uint new_sr = OPER_AL_16(); + m68ki_set_sr(new_sr); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_16_tos_pcdi(void) +{ + if(FLAG_S) + { + uint new_sr = OPER_PCDI_16(); + m68ki_set_sr(new_sr); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_16_tos_pcix(void) +{ + if(FLAG_S) + { + uint new_sr = OPER_PCIX_16(); + m68ki_set_sr(new_sr); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_16_tos_i(void) +{ + if(FLAG_S) + { + uint new_sr = OPER_I_16(); + m68ki_set_sr(new_sr); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_32_fru(void) +{ + if(FLAG_S) + { + AY = REG_USP; + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_move_32_tou(void) +{ + if(FLAG_S) + { + REG_USP = AY; + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_movem_16_re_pd(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = AY; + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + ea -= 2; + m68ki_write_16(ea, MASK_OUT_ABOVE_16(REG_DA[15-i])); + count++; + } + AY = ea; + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_re_ai(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_AI_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + m68ki_write_16(ea, MASK_OUT_ABOVE_16(REG_DA[i])); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_re_di(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_DI_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + m68ki_write_16(ea, MASK_OUT_ABOVE_16(REG_DA[i])); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_re_ix(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_IX_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + m68ki_write_16(ea, MASK_OUT_ABOVE_16(REG_DA[i])); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_re_aw(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AW_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + m68ki_write_16(ea, MASK_OUT_ABOVE_16(REG_DA[i])); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_re_al(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AL_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + m68ki_write_16(ea, MASK_OUT_ABOVE_16(REG_DA[i])); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_32_re_pd(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = AY; + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + ea -= 4; + m68ki_write_16(ea+2, REG_DA[15-i] & 0xFFFF ); + m68ki_write_16(ea, (REG_DA[15-i] >> 16) & 0xFFFF ); + count++; + } + AY = ea; + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_re_ai(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_AI_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + m68ki_write_32(ea, REG_DA[i]); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_re_di(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_DI_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + m68ki_write_32(ea, REG_DA[i]); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_re_ix(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_IX_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + m68ki_write_32(ea, REG_DA[i]); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_re_aw(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AW_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + m68ki_write_32(ea, REG_DA[i]); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_re_al(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AL_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + m68ki_write_32(ea, REG_DA[i]); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_16_er_pi(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = AY; + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = MAKE_INT_16(MASK_OUT_ABOVE_16(m68ki_read_16(ea))); + ea += 2; + count++; + } + AY = ea; + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_er_pcdi(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_PCDI_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = MAKE_INT_16(MASK_OUT_ABOVE_16(m68ki_read_pcrel_16(ea))); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_er_pcix(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_PCIX_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = MAKE_INT_16(MASK_OUT_ABOVE_16(m68ki_read_pcrel_16(ea))); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_er_ai(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_AI_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = MAKE_INT_16(MASK_OUT_ABOVE_16(m68ki_read_16(ea))); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_er_di(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_DI_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = MAKE_INT_16(MASK_OUT_ABOVE_16(m68ki_read_16(ea))); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_er_ix(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_IX_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = MAKE_INT_16(MASK_OUT_ABOVE_16(m68ki_read_16(ea))); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_er_aw(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AW_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = MAKE_INT_16(MASK_OUT_ABOVE_16(m68ki_read_16(ea))); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_16_er_al(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AL_16(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = MAKE_INT_16(MASK_OUT_ABOVE_16(m68ki_read_16(ea))); + ea += 2; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_W); +} + + +static void m68k_op_movem_32_er_pi(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = AY; + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = m68ki_read_32(ea); + ea += 4; + count++; + } + AY = ea; + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_er_pcdi(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_PCDI_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = m68ki_read_pcrel_32(ea); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_er_pcix(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_PCIX_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = m68ki_read_pcrel_32(ea); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_er_ai(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_AI_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = m68ki_read_32(ea); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_er_di(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_DI_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = m68ki_read_32(ea); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_er_ix(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AY_IX_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = m68ki_read_32(ea); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_er_aw(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AW_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = m68ki_read_32(ea); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movem_32_er_al(void) +{ + uint i = 0; + uint register_list = OPER_I_16(); + uint ea = EA_AL_32(); + uint count = 0; + + for(; i < 16; i++) + if(register_list & (1 << i)) + { + REG_DA[i] = m68ki_read_32(ea); + ea += 4; + count++; + } + + USE_CYCLES(count * CYC_MOVEM_L); +} + + +static void m68k_op_movep_16_re(void) +{ + uint ea = EA_AY_DI_16(); + uint src = DX; + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(src >> 8)); + m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src)); +} + + +static void m68k_op_movep_32_re(void) +{ + uint ea = EA_AY_DI_32(); + uint src = DX; + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(src >> 24)); + m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src >> 16)); + m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src >> 8)); + m68ki_write_8(ea += 2, MASK_OUT_ABOVE_8(src)); +} + + +static void m68k_op_movep_16_er(void) +{ + uint ea = EA_AY_DI_16(); + uint* r_dst = &DX; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | ((m68ki_read_8(ea) << 8) + m68ki_read_8(ea + 2)); +} + + +static void m68k_op_movep_32_er(void) +{ + uint ea = EA_AY_DI_32(); + + DX = (m68ki_read_8(ea) << 24) + (m68ki_read_8(ea + 2) << 16) + + (m68ki_read_8(ea + 4) << 8) + m68ki_read_8(ea + 6); +} + + +static void m68k_op_moveq_32(void) +{ + uint res = DX = MAKE_INT_8(MASK_OUT_ABOVE_8(REG_IR)); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_muls_16_d(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(DY); + uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + UseMulsCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_muls_16_ai(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AY_AI_16()); + uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + UseMulsCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_muls_16_pi(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AY_PI_16()); + uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + UseMulsCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_muls_16_pd(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AY_PD_16()); + uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + UseMulsCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_muls_16_di(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AY_DI_16()); + uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + UseMulsCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_muls_16_ix(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AY_IX_16()); + uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + UseMulsCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_muls_16_aw(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AW_16()); + uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + UseMulsCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_muls_16_al(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_AL_16()); + uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + UseMulsCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_muls_16_pcdi(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_PCDI_16()); + uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + UseMulsCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_muls_16_pcix(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_PCIX_16()); + uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + UseMulsCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_muls_16_i(void) +{ + uint* r_dst = &DX; + sint src = MAKE_INT_16(OPER_I_16()); + uint res = MASK_OUT_ABOVE_32( src * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst))); + + UseMulsCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_mulu_16_d(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(DY); + uint res = src * MASK_OUT_ABOVE_16(*r_dst); + + UseMuluCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_mulu_16_ai(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_AI_16(); + uint res = src * MASK_OUT_ABOVE_16(*r_dst); + + UseMuluCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_mulu_16_pi(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PI_16(); + uint res = src * MASK_OUT_ABOVE_16(*r_dst); + + UseMuluCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_mulu_16_pd(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PD_16(); + uint res = src * MASK_OUT_ABOVE_16(*r_dst); + + UseMuluCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_mulu_16_di(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_DI_16(); + uint res = src * MASK_OUT_ABOVE_16(*r_dst); + + UseMuluCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_mulu_16_ix(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_IX_16(); + uint res = src * MASK_OUT_ABOVE_16(*r_dst); + + UseMuluCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_mulu_16_aw(void) +{ + uint* r_dst = &DX; + uint src = OPER_AW_16(); + uint res = src * MASK_OUT_ABOVE_16(*r_dst); + + UseMuluCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_mulu_16_al(void) +{ + uint* r_dst = &DX; + uint src = OPER_AL_16(); + uint res = src * MASK_OUT_ABOVE_16(*r_dst); + + UseMuluCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_mulu_16_pcdi(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCDI_16(); + uint res = src * MASK_OUT_ABOVE_16(*r_dst); + + UseMuluCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_mulu_16_pcix(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCIX_16(); + uint res = src * MASK_OUT_ABOVE_16(*r_dst); + + UseMuluCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_mulu_16_i(void) +{ + uint* r_dst = &DX; + uint src = OPER_I_16(); + uint res = src * MASK_OUT_ABOVE_16(*r_dst); + + UseMuluCycles(src); + + *r_dst = res; + + FLAG_Z = res; + FLAG_N = NFLAG_32(res); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_nbcd_8_d(void) +{ + uint* r_dst = &DY; + uint dst = *r_dst; + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +static void m68k_op_nbcd_8_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint dst = m68ki_read_8(ea); + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +static void m68k_op_nbcd_8_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint dst = m68ki_read_8(ea); + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +static void m68k_op_nbcd_8_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint dst = m68ki_read_8(ea); + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +static void m68k_op_nbcd_8_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +static void m68k_op_nbcd_8_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +static void m68k_op_nbcd_8_di(void) +{ + uint ea = EA_AY_DI_8(); + uint dst = m68ki_read_8(ea); + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +static void m68k_op_nbcd_8_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint dst = m68ki_read_8(ea); + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +static void m68k_op_nbcd_8_aw(void) +{ + uint ea = EA_AW_8(); + uint dst = m68ki_read_8(ea); + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +static void m68k_op_nbcd_8_al(void) +{ + uint ea = EA_AL_8(); + uint dst = m68ki_read_8(ea); + uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + + if(res != 0x9a) + { + FLAG_V = ~res; /* Undefined V behavior */ + + if((res & 0x0f) == 0xa) + res = (res & 0xf0) + 0x10; + + res = MASK_OUT_ABOVE_8(res); + + FLAG_V &= res; /* Undefined V behavior part II */ + + m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); + + FLAG_Z |= res; + FLAG_C = CFLAG_SET; + FLAG_X = XFLAG_SET; + } + else + { + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + FLAG_X = XFLAG_CLEAR; + } + FLAG_N = NFLAG_8(res); /* Undefined N behavior */ +} + + +static void m68k_op_neg_8_d(void) +{ + uint* r_dst = &DY; + uint res = 0 - MASK_OUT_ABOVE_8(*r_dst); + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = *r_dst & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_neg_8_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = src & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_neg_8_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = src & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_neg_8_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = src & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_neg_8_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = src & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_neg_8_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = src & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_neg_8_di(void) +{ + uint ea = EA_AY_DI_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = src & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_neg_8_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = src & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_neg_8_aw(void) +{ + uint ea = EA_AW_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = src & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_neg_8_al(void) +{ + uint ea = EA_AL_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_8(res); + FLAG_C = FLAG_X = CFLAG_8(res); + FLAG_V = src & res; + FLAG_Z = MASK_OUT_ABOVE_8(res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_neg_16_d(void) +{ + uint* r_dst = &DY; + uint res = 0 - MASK_OUT_ABOVE_16(*r_dst); + + FLAG_N = NFLAG_16(res); + FLAG_C = FLAG_X = CFLAG_16(res); + FLAG_V = (*r_dst & res)>>8; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_neg_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_16(res); + FLAG_C = FLAG_X = CFLAG_16(res); + FLAG_V = (src & res)>>8; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_neg_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_16(res); + FLAG_C = FLAG_X = CFLAG_16(res); + FLAG_V = (src & res)>>8; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_neg_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_16(res); + FLAG_C = FLAG_X = CFLAG_16(res); + FLAG_V = (src & res)>>8; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_neg_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_16(res); + FLAG_C = FLAG_X = CFLAG_16(res); + FLAG_V = (src & res)>>8; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_neg_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_16(res); + FLAG_C = FLAG_X = CFLAG_16(res); + FLAG_V = (src & res)>>8; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_neg_16_aw(void) +{ + uint ea = EA_AW_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_16(res); + FLAG_C = FLAG_X = CFLAG_16(res); + FLAG_V = (src & res)>>8; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_neg_16_al(void) +{ + uint ea = EA_AL_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_16(res); + FLAG_C = FLAG_X = CFLAG_16(res); + FLAG_V = (src & res)>>8; + FLAG_Z = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_neg_32_d(void) +{ + uint* r_dst = &DY; + uint res = 0 - *r_dst; + + FLAG_N = NFLAG_32(res); + FLAG_C = FLAG_X = CFLAG_SUB_32(*r_dst, 0, res); + FLAG_V = (*r_dst & res)>>24; + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_neg_32_ai(void) +{ + uint ea = EA_AY_AI_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_32(res); + FLAG_C = FLAG_X = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_neg_32_pi(void) +{ + uint ea = EA_AY_PI_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_32(res); + FLAG_C = FLAG_X = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_neg_32_pd(void) +{ + uint ea = EA_AY_PD_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_32(res); + FLAG_C = FLAG_X = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_neg_32_di(void) +{ + uint ea = EA_AY_DI_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_32(res); + FLAG_C = FLAG_X = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_neg_32_ix(void) +{ + uint ea = EA_AY_IX_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_32(res); + FLAG_C = FLAG_X = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_neg_32_aw(void) +{ + uint ea = EA_AW_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_32(res); + FLAG_C = FLAG_X = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_neg_32_al(void) +{ + uint ea = EA_AL_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - src; + + FLAG_N = NFLAG_32(res); + FLAG_C = FLAG_X = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + FLAG_Z = MASK_OUT_ABOVE_32(res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_negx_8_d(void) +{ + uint* r_dst = &DY; + uint res = 0 - MASK_OUT_ABOVE_8(*r_dst) - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = *r_dst & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; +} + + +static void m68k_op_negx_8_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = src & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_negx_8_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = src & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_negx_8_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = src & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_negx_8_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = src & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_negx_8_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = src & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_negx_8_di(void) +{ + uint ea = EA_AY_DI_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = src & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_negx_8_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = src & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_negx_8_aw(void) +{ + uint ea = EA_AW_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = src & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_negx_8_al(void) +{ + uint ea = EA_AL_8(); + uint src = m68ki_read_8(ea); + uint res = 0 - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = src & res; + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_negx_16_d(void) +{ + uint* r_dst = &DY; + uint res = 0 - MASK_OUT_ABOVE_16(*r_dst) - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = (*r_dst & res)>>8; + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; +} + + +static void m68k_op_negx_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - MASK_OUT_ABOVE_16(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = (src & res)>>8; + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_negx_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - MASK_OUT_ABOVE_16(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = (src & res)>>8; + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_negx_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - MASK_OUT_ABOVE_16(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = (src & res)>>8; + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_negx_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - MASK_OUT_ABOVE_16(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = (src & res)>>8; + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_negx_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - MASK_OUT_ABOVE_16(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = (src & res)>>8; + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_negx_16_aw(void) +{ + uint ea = EA_AW_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - MASK_OUT_ABOVE_16(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = (src & res)>>8; + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_negx_16_al(void) +{ + uint ea = EA_AL_16(); + uint src = m68ki_read_16(ea); + uint res = 0 - MASK_OUT_ABOVE_16(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = (src & res)>>8; + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_negx_32_d(void) +{ + uint* r_dst = &DY; + uint res = 0 - MASK_OUT_ABOVE_32(*r_dst) - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(*r_dst, 0, res); + FLAG_V = (*r_dst & res)>>24; + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + *r_dst = res; +} + + +static void m68k_op_negx_32_ai(void) +{ + uint ea = EA_AY_AI_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - MASK_OUT_ABOVE_32(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_negx_32_pi(void) +{ + uint ea = EA_AY_PI_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - MASK_OUT_ABOVE_32(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_negx_32_pd(void) +{ + uint ea = EA_AY_PD_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - MASK_OUT_ABOVE_32(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_negx_32_di(void) +{ + uint ea = EA_AY_DI_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - MASK_OUT_ABOVE_32(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_negx_32_ix(void) +{ + uint ea = EA_AY_IX_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - MASK_OUT_ABOVE_32(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_negx_32_aw(void) +{ + uint ea = EA_AW_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - MASK_OUT_ABOVE_32(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_negx_32_al(void) +{ + uint ea = EA_AL_32(); + uint src = m68ki_read_32(ea); + uint res = 0 - MASK_OUT_ABOVE_32(src) - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, 0, res); + FLAG_V = (src & res)>>24; + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_nop(void) +{ +} + + +static void m68k_op_not_8_d(void) +{ + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_8(~*r_dst); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_8_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint res = MASK_OUT_ABOVE_8(~m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_8_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint res = MASK_OUT_ABOVE_8(~m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_8_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint res = MASK_OUT_ABOVE_8(~m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_8_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint res = MASK_OUT_ABOVE_8(~m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_8_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint res = MASK_OUT_ABOVE_8(~m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_8_di(void) +{ + uint ea = EA_AY_DI_8(); + uint res = MASK_OUT_ABOVE_8(~m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_8_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint res = MASK_OUT_ABOVE_8(~m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_8_aw(void) +{ + uint ea = EA_AW_8(); + uint res = MASK_OUT_ABOVE_8(~m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_8_al(void) +{ + uint ea = EA_AL_8(); + uint res = MASK_OUT_ABOVE_8(~m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_16_d(void) +{ + uint* r_dst = &DY; + uint res = MASK_OUT_ABOVE_16(~*r_dst); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint res = MASK_OUT_ABOVE_16(~m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint res = MASK_OUT_ABOVE_16(~m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint res = MASK_OUT_ABOVE_16(~m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint res = MASK_OUT_ABOVE_16(~m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint res = MASK_OUT_ABOVE_16(~m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_16_aw(void) +{ + uint ea = EA_AW_16(); + uint res = MASK_OUT_ABOVE_16(~m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_16_al(void) +{ + uint ea = EA_AL_16(); + uint res = MASK_OUT_ABOVE_16(~m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_32_d(void) +{ + uint* r_dst = &DY; + uint res = *r_dst = MASK_OUT_ABOVE_32(~*r_dst); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_32_ai(void) +{ + uint ea = EA_AY_AI_32(); + uint res = MASK_OUT_ABOVE_32(~m68ki_read_32(ea)); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_32_pi(void) +{ + uint ea = EA_AY_PI_32(); + uint res = MASK_OUT_ABOVE_32(~m68ki_read_32(ea)); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_32_pd(void) +{ + uint ea = EA_AY_PD_32(); + uint res = MASK_OUT_ABOVE_32(~m68ki_read_32(ea)); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_32_di(void) +{ + uint ea = EA_AY_DI_32(); + uint res = MASK_OUT_ABOVE_32(~m68ki_read_32(ea)); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_32_ix(void) +{ + uint ea = EA_AY_IX_32(); + uint res = MASK_OUT_ABOVE_32(~m68ki_read_32(ea)); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_32_aw(void) +{ + uint ea = EA_AW_32(); + uint res = MASK_OUT_ABOVE_32(~m68ki_read_32(ea)); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_not_32_al(void) +{ + uint ea = EA_AL_32(); + uint res = MASK_OUT_ABOVE_32(~m68ki_read_32(ea)); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_d(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= MASK_OUT_ABOVE_8(DY))); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_ai(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_AY_AI_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_pi(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_AY_PI_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_pi7(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_A7_PI_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_pd(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_AY_PD_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_pd7(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_A7_PD_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_di(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_AY_DI_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_ix(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_AY_IX_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_aw(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_AW_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_al(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_AL_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_pcdi(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_PCDI_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_pcix(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_PCIX_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_er_i(void) +{ + uint res = MASK_OUT_ABOVE_8((DX |= OPER_I_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_er_d(void) +{ + uint res = MASK_OUT_ABOVE_16((DX |= MASK_OUT_ABOVE_16(DY))); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_er_ai(void) +{ + uint res = MASK_OUT_ABOVE_16((DX |= OPER_AY_AI_16())); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_er_pi(void) +{ + uint res = MASK_OUT_ABOVE_16((DX |= OPER_AY_PI_16())); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_er_pd(void) +{ + uint res = MASK_OUT_ABOVE_16((DX |= OPER_AY_PD_16())); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_er_di(void) +{ + uint res = MASK_OUT_ABOVE_16((DX |= OPER_AY_DI_16())); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_er_ix(void) +{ + uint res = MASK_OUT_ABOVE_16((DX |= OPER_AY_IX_16())); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_er_aw(void) +{ + uint res = MASK_OUT_ABOVE_16((DX |= OPER_AW_16())); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_er_al(void) +{ + uint res = MASK_OUT_ABOVE_16((DX |= OPER_AL_16())); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_er_pcdi(void) +{ + uint res = MASK_OUT_ABOVE_16((DX |= OPER_PCDI_16())); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_er_pcix(void) +{ + uint res = MASK_OUT_ABOVE_16((DX |= OPER_PCIX_16())); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_er_i(void) +{ + uint res = MASK_OUT_ABOVE_16((DX |= OPER_I_16())); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_er_d(void) +{ + uint res = DX |= DY; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_er_ai(void) +{ + uint res = DX |= OPER_AY_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_er_pi(void) +{ + uint res = DX |= OPER_AY_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_er_pd(void) +{ + uint res = DX |= OPER_AY_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_er_di(void) +{ + uint res = DX |= OPER_AY_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_er_ix(void) +{ + uint res = DX |= OPER_AY_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_er_aw(void) +{ + uint res = DX |= OPER_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_er_al(void) +{ + uint res = DX |= OPER_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_er_pcdi(void) +{ + uint res = DX |= OPER_PCDI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_er_pcix(void) +{ + uint res = DX |= OPER_PCIX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_er_i(void) +{ + uint res = DX |= OPER_I_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_re_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint res = MASK_OUT_ABOVE_8(DX | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_re_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint res = MASK_OUT_ABOVE_8(DX | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_re_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint res = MASK_OUT_ABOVE_8(DX | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_re_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint res = MASK_OUT_ABOVE_8(DX | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_re_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint res = MASK_OUT_ABOVE_8(DX | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_re_di(void) +{ + uint ea = EA_AY_DI_8(); + uint res = MASK_OUT_ABOVE_8(DX | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_re_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint res = MASK_OUT_ABOVE_8(DX | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_re_aw(void) +{ + uint ea = EA_AW_8(); + uint res = MASK_OUT_ABOVE_8(DX | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_8_re_al(void) +{ + uint ea = EA_AL_8(); + uint res = MASK_OUT_ABOVE_8(DX | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_re_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint res = MASK_OUT_ABOVE_16(DX | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_re_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint res = MASK_OUT_ABOVE_16(DX | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_re_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint res = MASK_OUT_ABOVE_16(DX | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_re_di(void) +{ + uint ea = EA_AY_DI_16(); + uint res = MASK_OUT_ABOVE_16(DX | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_re_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint res = MASK_OUT_ABOVE_16(DX | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_re_aw(void) +{ + uint ea = EA_AW_16(); + uint res = MASK_OUT_ABOVE_16(DX | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_16_re_al(void) +{ + uint ea = EA_AL_16(); + uint res = MASK_OUT_ABOVE_16(DX | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_re_ai(void) +{ + uint ea = EA_AY_AI_32(); + uint res = DX | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_re_pi(void) +{ + uint ea = EA_AY_PI_32(); + uint res = DX | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_re_pd(void) +{ + uint ea = EA_AY_PD_32(); + uint res = DX | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_re_di(void) +{ + uint ea = EA_AY_DI_32(); + uint res = DX | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_re_ix(void) +{ + uint ea = EA_AY_IX_32(); + uint res = DX | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_re_aw(void) +{ + uint ea = EA_AW_32(); + uint res = DX | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_or_32_re_al(void) +{ + uint ea = EA_AL_32(); + uint res = DX | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_8_d(void) +{ + uint res = MASK_OUT_ABOVE_8((DY |= OPER_I_8())); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_8_ai(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_AI_8(); + uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_8_pi(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_PI_8(); + uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_8_pi7(void) +{ + uint src = OPER_I_8(); + uint ea = EA_A7_PI_8(); + uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_8_pd(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_PD_8(); + uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_8_pd7(void) +{ + uint src = OPER_I_8(); + uint ea = EA_A7_PD_8(); + uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_8_di(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_DI_8(); + uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_8_ix(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_IX_8(); + uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_8_aw(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AW_8(); + uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_8_al(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AL_8(); + uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea)); + + m68ki_write_8(ea, res); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_16_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY |= OPER_I_16()); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_16_ai(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_AI_16(); + uint res = MASK_OUT_ABOVE_16(src | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_16_pi(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_PI_16(); + uint res = MASK_OUT_ABOVE_16(src | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_16_pd(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_PD_16(); + uint res = MASK_OUT_ABOVE_16(src | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_16_di(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_DI_16(); + uint res = MASK_OUT_ABOVE_16(src | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_16_ix(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_IX_16(); + uint res = MASK_OUT_ABOVE_16(src | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_16_aw(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AW_16(); + uint res = MASK_OUT_ABOVE_16(src | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_16_al(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AL_16(); + uint res = MASK_OUT_ABOVE_16(src | m68ki_read_16(ea)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_32_d(void) +{ + uint res = DY |= OPER_I_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_32_ai(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_AI_32(); + uint res = src | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_32_pi(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_PI_32(); + uint res = src | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_32_pd(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_PD_32(); + uint res = src | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_32_di(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_DI_32(); + uint res = src | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_32_ix(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_IX_32(); + uint res = src | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_32_aw(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AW_32(); + uint res = src | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_32_al(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AL_32(); + uint res = src | m68ki_read_32(ea); + + m68ki_write_32(ea, res); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ori_16_toc(void) +{ + m68ki_set_ccr(m68ki_get_ccr() | OPER_I_16()); +} + + +static void m68k_op_ori_16_tos(void) +{ + if(FLAG_S) + { + uint src = OPER_I_16(); + m68ki_set_sr(m68ki_get_sr() | src); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_pea_32_ai(void) +{ + uint ea = EA_AY_AI_32(); + + m68ki_push_32(ea); +} + + +static void m68k_op_pea_32_di(void) +{ + uint ea = EA_AY_DI_32(); + + m68ki_push_32(ea); +} + + +static void m68k_op_pea_32_ix(void) +{ + uint ea = EA_AY_IX_32(); + + m68ki_push_32(ea); +} + + +static void m68k_op_pea_32_aw(void) +{ + uint ea = EA_AW_32(); + + m68ki_push_32(ea); +} + + +static void m68k_op_pea_32_al(void) +{ + uint ea = EA_AL_32(); + + m68ki_push_32(ea); +} + + +static void m68k_op_pea_32_pcdi(void) +{ + uint ea = EA_PCDI_32(); + + m68ki_push_32(ea); +} + + +static void m68k_op_pea_32_pcix(void) +{ + uint ea = EA_PCIX_32(); + + m68ki_push_32(ea); +} + + +static void m68k_op_reset(void) +{ + if(FLAG_S) + { + m68ki_output_reset() /* auto-disable (see m68kcpu.h) */ + USE_CYCLES(CYC_RESET); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_ror_8_s(void) +{ + uint* r_dst = &DY; + uint orig_shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint shift = orig_shift & 7; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROR_8(src, shift); + + if(orig_shift != 0) + USE_CYCLES(orig_shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = src << (9-orig_shift); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_16_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROR_16(src, shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src << (9-shift); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_32_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint64 src = *r_dst; + uint res = ROR_32(src, shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = src << (9-shift); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_8_r(void) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift & 7; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROR_8(src, shift); + + if(orig_shift != 0) + { + USE_CYCLES(orig_shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + FLAG_C = src << (8-((shift-1)&7)); + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_8(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_16_r(void) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift & 15; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROR_16(src, shift); + + if(orig_shift != 0) + { + USE_CYCLES(orig_shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + FLAG_C = (src >> ((shift - 1) & 15)) << 8; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_32_r(void) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift & 31; + uint64 src = *r_dst; + uint res = ROR_32(src, shift); + + if(orig_shift != 0) + { + USE_CYCLES(orig_shift * CYC_SHIFT); + + *r_dst = res; + FLAG_C = (src >> ((shift - 1) & 31)) << 8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_16(src, 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_16(src, 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_16(src, 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_16(src, 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_16(src, 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_16_aw(void) +{ + uint ea = EA_AW_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_16(src, 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_ror_16_al(void) +{ + uint ea = EA_AL_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_16(src, 1); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src << 8; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_8_s(void) +{ + uint* r_dst = &DY; + uint orig_shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint shift = orig_shift & 7; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROL_8(src, shift); + + if(orig_shift != 0) + USE_CYCLES(orig_shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_C = src << orig_shift; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_16_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROL_16(src, shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src >> (8-shift); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_32_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint64 src = *r_dst; + uint res = ROL_32(src, shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_C = src >> (24-shift); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_8_r(void) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift & 7; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROL_8(src, shift); + + if(orig_shift != 0) + { + USE_CYCLES(orig_shift * CYC_SHIFT); + + if(shift != 0) + { + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + FLAG_C = src << shift; + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + FLAG_C = (src & 1)<<8; + FLAG_N = NFLAG_8(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_8(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_16_r(void) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift & 15; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = MASK_OUT_ABOVE_16(ROL_16(src, shift)); + + if(orig_shift != 0) + { + USE_CYCLES(orig_shift * CYC_SHIFT); + + if(shift != 0) + { + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + FLAG_C = (src << shift) >> 8; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + FLAG_C = (src & 1)<<8; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_16(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_32_r(void) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift & 31; + uint64 src = *r_dst; + uint res = ROL_32(src, shift); + + if(orig_shift != 0) + { + USE_CYCLES(orig_shift * CYC_SHIFT); + + *r_dst = res; + + FLAG_C = (src >> ((32 - shift) & 0x1f)) << 8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = CFLAG_CLEAR; + FLAG_N = NFLAG_32(src); + FLAG_Z = src; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(ROL_16(src, 1)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(ROL_16(src, 1)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(ROL_16(src, 1)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(ROL_16(src, 1)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(ROL_16(src, 1)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_16_aw(void) +{ + uint ea = EA_AW_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(ROL_16(src, 1)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rol_16_al(void) +{ + uint ea = EA_AL_16(); + uint src = m68ki_read_16(ea); + uint res = MASK_OUT_ABOVE_16(ROL_16(src, 1)); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_C = src >> 7; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxr_8_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROR_9(src | (XFLAG_AS_1() << 8), shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + FLAG_C = FLAG_X = res; + res = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxr_16_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROR_17(src | (XFLAG_AS_1() << 16), shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxr_32_s(void) +{ +#if M68K_USE_64_BIT + + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint64 src = *r_dst; + uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + res = ROR_33_64(res, shift); + + FLAG_C = FLAG_X = res >> 24; + res = MASK_OUT_ABOVE_32(res); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + +#else + + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32((ROR_33(src, shift) & ~(1 << (32 - shift))) | (XFLAG_AS_1() << (32 - shift))); + uint new_x_flag = src & (1 << (shift - 1)); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = res; + + FLAG_C = FLAG_X = (new_x_flag != 0)<<8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + +#endif +} + + +static void m68k_op_roxr_8_r(void) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + + if(orig_shift != 0) + { + uint shift = orig_shift % 9; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROR_9(src | (XFLAG_AS_1() << 8), shift); + + USE_CYCLES(orig_shift * CYC_SHIFT); + + FLAG_C = FLAG_X = res; + res = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = FLAG_X; + FLAG_N = NFLAG_8(*r_dst); + FLAG_Z = MASK_OUT_ABOVE_8(*r_dst); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxr_16_r(void) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + + if(orig_shift != 0) + { + uint shift = orig_shift % 17; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROR_17(src | (XFLAG_AS_1() << 16), shift); + + USE_CYCLES(orig_shift * CYC_SHIFT); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = FLAG_X; + FLAG_N = NFLAG_16(*r_dst); + FLAG_Z = MASK_OUT_ABOVE_16(*r_dst); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxr_32_r(void) +{ +#if M68K_USE_64_BIT + + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + + if(orig_shift != 0) + { + uint shift = orig_shift % 33; + uint64 src = *r_dst; + uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); + + res = ROR_33_64(res, shift); + + USE_CYCLES(orig_shift * CYC_SHIFT); + + FLAG_C = FLAG_X = res >> 24; + res = MASK_OUT_ABOVE_32(res); + + *r_dst = res; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = FLAG_X; + FLAG_N = NFLAG_32(*r_dst); + FLAG_Z = *r_dst; + FLAG_V = VFLAG_CLEAR; + +#else + + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift % 33; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32((ROR_33(src, shift) & ~(1 << (32 - shift))) | (XFLAG_AS_1() << (32 - shift))); + uint new_x_flag = src & (1 << (shift - 1)); + + if(orig_shift != 0) + USE_CYCLES(orig_shift * CYC_SHIFT); + + if(shift != 0) + { + *r_dst = res; + FLAG_X = (new_x_flag != 0)<<8; + } + else + res = src; + FLAG_C = FLAG_X; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + +#endif +} + + +static void m68k_op_roxr_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxr_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxr_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxr_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxr_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxr_16_aw(void) +{ + uint ea = EA_AW_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxr_16_al(void) +{ + uint ea = EA_AL_16(); + uint src = m68ki_read_16(ea); + uint res = ROR_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxl_8_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROL_9(src | (XFLAG_AS_1() << 8), shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + FLAG_C = FLAG_X = res; + res = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxl_16_s(void) +{ + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROL_17(src | (XFLAG_AS_1() << 16), shift); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxl_32_s(void) +{ +#if M68K_USE_64_BIT + + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint64 src = *r_dst; + uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + res = ROL_33_64(res, shift); + + FLAG_C = FLAG_X = res >> 24; + res = MASK_OUT_ABOVE_32(res); + + *r_dst = res; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + +#else + + uint* r_dst = &DY; + uint shift = (((REG_IR >> 9) - 1) & 7) + 1; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32((ROL_33(src, shift) & ~(1 << (shift - 1))) | (XFLAG_AS_1() << (shift - 1))); + uint new_x_flag = src & (1 << (32 - shift)); + + if(shift != 0) + USE_CYCLES(shift * CYC_SHIFT); + + *r_dst = res; + + FLAG_C = FLAG_X = (new_x_flag != 0)<<8; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + +#endif +} + + +static void m68k_op_roxl_8_r(void) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + + + if(orig_shift != 0) + { + uint shift = orig_shift % 9; + uint src = MASK_OUT_ABOVE_8(*r_dst); + uint res = ROL_9(src | (XFLAG_AS_1() << 8), shift); + + USE_CYCLES(orig_shift * CYC_SHIFT); + + FLAG_C = FLAG_X = res; + res = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = FLAG_X; + FLAG_N = NFLAG_8(*r_dst); + FLAG_Z = MASK_OUT_ABOVE_8(*r_dst); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxl_16_r(void) +{ + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + + if(orig_shift != 0) + { + uint shift = orig_shift % 17; + uint src = MASK_OUT_ABOVE_16(*r_dst); + uint res = ROL_17(src | (XFLAG_AS_1() << 16), shift); + + USE_CYCLES(orig_shift * CYC_SHIFT); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = FLAG_X; + FLAG_N = NFLAG_16(*r_dst); + FLAG_Z = MASK_OUT_ABOVE_16(*r_dst); + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxl_32_r(void) +{ +#if M68K_USE_64_BIT + + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + + if(orig_shift != 0) + { + uint shift = orig_shift % 33; + uint64 src = *r_dst; + uint64 res = src | (((uint64)XFLAG_AS_1()) << 32); + + res = ROL_33_64(res, shift); + + USE_CYCLES(orig_shift * CYC_SHIFT); + + FLAG_C = FLAG_X = res >> 24; + res = MASK_OUT_ABOVE_32(res); + + *r_dst = res; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + return; + } + + FLAG_C = FLAG_X; + FLAG_N = NFLAG_32(*r_dst); + FLAG_Z = *r_dst; + FLAG_V = VFLAG_CLEAR; + +#else + + uint* r_dst = &DY; + uint orig_shift = DX & 0x3f; + uint shift = orig_shift % 33; + uint src = *r_dst; + uint res = MASK_OUT_ABOVE_32((ROL_33(src, shift) & ~(1 << (shift - 1))) | (XFLAG_AS_1() << (shift - 1))); + uint new_x_flag = src & (1 << (32 - shift)); + + if(orig_shift != 0) + USE_CYCLES(orig_shift * CYC_SHIFT); + + if(shift != 0) + { + *r_dst = res; + FLAG_X = (new_x_flag != 0)<<8; + } + else + res = src; + FLAG_C = FLAG_X; + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + +#endif +} + + +static void m68k_op_roxl_16_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = m68ki_read_16(ea); + uint res = ROL_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxl_16_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = m68ki_read_16(ea); + uint res = ROL_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxl_16_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = m68ki_read_16(ea); + uint res = ROL_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxl_16_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = m68ki_read_16(ea); + uint res = ROL_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxl_16_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = m68ki_read_16(ea); + uint res = ROL_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxl_16_aw(void) +{ + uint ea = EA_AW_16(); + uint src = m68ki_read_16(ea); + uint res = ROL_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_roxl_16_al(void) +{ + uint ea = EA_AL_16(); + uint src = m68ki_read_16(ea); + uint res = ROL_17(src | (XFLAG_AS_1() << 16), 1); + + FLAG_C = FLAG_X = res >> 8; + res = MASK_OUT_ABOVE_16(res); + + m68ki_write_16(ea, res); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_rte_32(void) +{ + if(FLAG_S) + { + uint new_sr; + uint new_pc; + + new_sr = m68ki_pull_16(); + new_pc = m68ki_pull_32(); + m68ki_jump(new_pc); + m68ki_set_sr(new_sr); + +#if M68K_EMULATE_ADDRESS_ERROR + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; +#endif + + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_rtr_32(void) +{ + m68ki_set_ccr(m68ki_pull_16()); + m68ki_jump(m68ki_pull_32()); +} + + +static void m68k_op_rts_32(void) +{ + m68ki_jump(m68ki_pull_32()); +} + + +static void m68k_op_sbcd_8_rr(void) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + +/* FLAG_V = ~res; */ /* Undefined V behavior */ + FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to assume cleared. */ + + if(res > 9) + res -= 6; + res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); + if(res > 0x99) + { + res += 0xa0; + FLAG_X = FLAG_C = CFLAG_SET; + FLAG_N = NFLAG_SET; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */ + } + else + FLAG_N = FLAG_X = FLAG_C = 0; + + res = MASK_OUT_ABOVE_8(res); + +/* FLAG_V &= res; */ /* Undefined V behavior part II */ +/* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */ + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; +} + + +static void m68k_op_sbcd_8_mm_ax7(void) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + +/* FLAG_V = ~res; */ /* Undefined V behavior */ + FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */ + + if(res > 9) + res -= 6; + res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); + if(res > 0x99) + { + res += 0xa0; + FLAG_X = FLAG_C = CFLAG_SET; + FLAG_N = NFLAG_SET; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */ + } + else + FLAG_N = FLAG_X = FLAG_C = 0; + + res = MASK_OUT_ABOVE_8(res); + +/* FLAG_V &= res; */ /* Undefined V behavior part II */ +/* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */ + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_sbcd_8_mm_ay7(void) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + +/* FLAG_V = ~res; */ /* Undefined V behavior */ + FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */ + + if(res > 9) + res -= 6; + res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); + if(res > 0x99) + { + res += 0xa0; + FLAG_X = FLAG_C = CFLAG_SET; + FLAG_N = NFLAG_SET; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */ + } + else + FLAG_N = FLAG_X = FLAG_C = 0; + + res = MASK_OUT_ABOVE_8(res); + +/* FLAG_V &= res; */ /* Undefined V behavior part II */ +/* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */ + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_sbcd_8_mm_axy7(void) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + +/* FLAG_V = ~res; */ /* Undefined V behavior */ + FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */ + + if(res > 9) + res -= 6; + res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); + if(res > 0x99) + { + res += 0xa0; + FLAG_X = FLAG_C = CFLAG_SET; + FLAG_N = NFLAG_SET; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */ + } + else + FLAG_N = FLAG_X = FLAG_C = 0; + + res = MASK_OUT_ABOVE_8(res); + +/* FLAG_V &= res; */ /* Undefined V behavior part II */ +/* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */ + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_sbcd_8_mm(void) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + +/* FLAG_V = ~res; */ /* Undefined V behavior */ + FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */ + + if(res > 9) + res -= 6; + res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); + if(res > 0x99) + { + res += 0xa0; + FLAG_X = FLAG_C = CFLAG_SET; + FLAG_N = NFLAG_SET; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */ + } + else + FLAG_N = FLAG_X = FLAG_C = 0; + + res = MASK_OUT_ABOVE_8(res); + +/* FLAG_V &= res; */ /* Undefined V behavior part II */ +/* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */ + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_st_8_d(void) +{ + DY |= 0xff; +} + + +static void m68k_op_st_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), 0xff); +} + + +static void m68k_op_st_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), 0xff); +} + + +static void m68k_op_st_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), 0xff); +} + + +static void m68k_op_st_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), 0xff); +} + + +static void m68k_op_st_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), 0xff); +} + + +static void m68k_op_st_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), 0xff); +} + + +static void m68k_op_st_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), 0xff); +} + + +static void m68k_op_st_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), 0xff); +} + + +static void m68k_op_st_8_al(void) +{ + m68ki_write_8(EA_AL_8(), 0xff); +} + + +static void m68k_op_sf_8_d(void) +{ + DY &= 0xffffff00; +} + + +static void m68k_op_sf_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), 0); +} + + +static void m68k_op_sf_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), 0); +} + + +static void m68k_op_sf_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), 0); +} + + +static void m68k_op_sf_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), 0); +} + + +static void m68k_op_sf_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), 0); +} + + +static void m68k_op_sf_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), 0); +} + + +static void m68k_op_sf_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), 0); +} + + +static void m68k_op_sf_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), 0); +} + + +static void m68k_op_sf_8_al(void) +{ + m68ki_write_8(EA_AL_8(), 0); +} + + +static void m68k_op_shi_8_d(void) +{ + if(COND_HI()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_sls_8_d(void) +{ + if(COND_LS()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_scc_8_d(void) +{ + if(COND_CC()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_scs_8_d(void) +{ + if(COND_CS()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_sne_8_d(void) +{ + if(COND_NE()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_seq_8_d(void) +{ + if(COND_EQ()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_svc_8_d(void) +{ + if(COND_VC()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_svs_8_d(void) +{ + if(COND_VS()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_spl_8_d(void) +{ + if(COND_PL()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_smi_8_d(void) +{ + if(COND_MI()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_sge_8_d(void) +{ + if(COND_GE()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_slt_8_d(void) +{ + if(COND_LT()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_sgt_8_d(void) +{ + if(COND_GT()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_sle_8_d(void) +{ + if(COND_LE()) + { + DY |= 0xff; + USE_CYCLES(CYC_SCC_R_TRUE); + return; + } + DY &= 0xffffff00; +} + + +static void m68k_op_shi_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_HI() ? 0xff : 0); +} + + +static void m68k_op_shi_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_HI() ? 0xff : 0); +} + + +static void m68k_op_shi_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_HI() ? 0xff : 0); +} + + +static void m68k_op_shi_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_HI() ? 0xff : 0); +} + + +static void m68k_op_shi_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_HI() ? 0xff : 0); +} + + +static void m68k_op_shi_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_HI() ? 0xff : 0); +} + + +static void m68k_op_shi_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_HI() ? 0xff : 0); +} + + +static void m68k_op_shi_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_HI() ? 0xff : 0); +} + + +static void m68k_op_shi_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_HI() ? 0xff : 0); +} + + +static void m68k_op_sls_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_LS() ? 0xff : 0); +} + + +static void m68k_op_sls_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_LS() ? 0xff : 0); +} + + +static void m68k_op_sls_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_LS() ? 0xff : 0); +} + + +static void m68k_op_sls_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_LS() ? 0xff : 0); +} + + +static void m68k_op_sls_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_LS() ? 0xff : 0); +} + + +static void m68k_op_sls_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_LS() ? 0xff : 0); +} + + +static void m68k_op_sls_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_LS() ? 0xff : 0); +} + + +static void m68k_op_sls_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_LS() ? 0xff : 0); +} + + +static void m68k_op_sls_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_LS() ? 0xff : 0); +} + + +static void m68k_op_scc_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_CC() ? 0xff : 0); +} + + +static void m68k_op_scc_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_CC() ? 0xff : 0); +} + + +static void m68k_op_scc_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_CC() ? 0xff : 0); +} + + +static void m68k_op_scc_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_CC() ? 0xff : 0); +} + + +static void m68k_op_scc_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_CC() ? 0xff : 0); +} + + +static void m68k_op_scc_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_CC() ? 0xff : 0); +} + + +static void m68k_op_scc_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_CC() ? 0xff : 0); +} + + +static void m68k_op_scc_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_CC() ? 0xff : 0); +} + + +static void m68k_op_scc_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_CC() ? 0xff : 0); +} + + +static void m68k_op_scs_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_CS() ? 0xff : 0); +} + + +static void m68k_op_scs_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_CS() ? 0xff : 0); +} + + +static void m68k_op_scs_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_CS() ? 0xff : 0); +} + + +static void m68k_op_scs_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_CS() ? 0xff : 0); +} + + +static void m68k_op_scs_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_CS() ? 0xff : 0); +} + + +static void m68k_op_scs_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_CS() ? 0xff : 0); +} + + +static void m68k_op_scs_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_CS() ? 0xff : 0); +} + + +static void m68k_op_scs_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_CS() ? 0xff : 0); +} + + +static void m68k_op_scs_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_CS() ? 0xff : 0); +} + + +static void m68k_op_sne_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_NE() ? 0xff : 0); +} + + +static void m68k_op_sne_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_NE() ? 0xff : 0); +} + + +static void m68k_op_sne_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_NE() ? 0xff : 0); +} + + +static void m68k_op_sne_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_NE() ? 0xff : 0); +} + + +static void m68k_op_sne_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_NE() ? 0xff : 0); +} + + +static void m68k_op_sne_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_NE() ? 0xff : 0); +} + + +static void m68k_op_sne_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_NE() ? 0xff : 0); +} + + +static void m68k_op_sne_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_NE() ? 0xff : 0); +} + + +static void m68k_op_sne_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_NE() ? 0xff : 0); +} + + +static void m68k_op_seq_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_EQ() ? 0xff : 0); +} + + +static void m68k_op_seq_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_EQ() ? 0xff : 0); +} + + +static void m68k_op_seq_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_EQ() ? 0xff : 0); +} + + +static void m68k_op_seq_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_EQ() ? 0xff : 0); +} + + +static void m68k_op_seq_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_EQ() ? 0xff : 0); +} + + +static void m68k_op_seq_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_EQ() ? 0xff : 0); +} + + +static void m68k_op_seq_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_EQ() ? 0xff : 0); +} + + +static void m68k_op_seq_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_EQ() ? 0xff : 0); +} + + +static void m68k_op_seq_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_EQ() ? 0xff : 0); +} + + +static void m68k_op_svc_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_VC() ? 0xff : 0); +} + + +static void m68k_op_svc_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_VC() ? 0xff : 0); +} + + +static void m68k_op_svc_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_VC() ? 0xff : 0); +} + + +static void m68k_op_svc_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_VC() ? 0xff : 0); +} + + +static void m68k_op_svc_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_VC() ? 0xff : 0); +} + + +static void m68k_op_svc_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_VC() ? 0xff : 0); +} + + +static void m68k_op_svc_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_VC() ? 0xff : 0); +} + + +static void m68k_op_svc_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_VC() ? 0xff : 0); +} + + +static void m68k_op_svc_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_VC() ? 0xff : 0); +} + + +static void m68k_op_svs_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_VS() ? 0xff : 0); +} + + +static void m68k_op_svs_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_VS() ? 0xff : 0); +} + + +static void m68k_op_svs_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_VS() ? 0xff : 0); +} + + +static void m68k_op_svs_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_VS() ? 0xff : 0); +} + + +static void m68k_op_svs_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_VS() ? 0xff : 0); +} + + +static void m68k_op_svs_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_VS() ? 0xff : 0); +} + + +static void m68k_op_svs_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_VS() ? 0xff : 0); +} + + +static void m68k_op_svs_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_VS() ? 0xff : 0); +} + + +static void m68k_op_svs_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_VS() ? 0xff : 0); +} + + +static void m68k_op_spl_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_PL() ? 0xff : 0); +} + + +static void m68k_op_spl_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_PL() ? 0xff : 0); +} + + +static void m68k_op_spl_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_PL() ? 0xff : 0); +} + + +static void m68k_op_spl_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_PL() ? 0xff : 0); +} + + +static void m68k_op_spl_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_PL() ? 0xff : 0); +} + + +static void m68k_op_spl_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_PL() ? 0xff : 0); +} + + +static void m68k_op_spl_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_PL() ? 0xff : 0); +} + + +static void m68k_op_spl_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_PL() ? 0xff : 0); +} + + +static void m68k_op_spl_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_PL() ? 0xff : 0); +} + + +static void m68k_op_smi_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_MI() ? 0xff : 0); +} + + +static void m68k_op_smi_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_MI() ? 0xff : 0); +} + + +static void m68k_op_smi_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_MI() ? 0xff : 0); +} + + +static void m68k_op_smi_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_MI() ? 0xff : 0); +} + + +static void m68k_op_smi_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_MI() ? 0xff : 0); +} + + +static void m68k_op_smi_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_MI() ? 0xff : 0); +} + + +static void m68k_op_smi_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_MI() ? 0xff : 0); +} + + +static void m68k_op_smi_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_MI() ? 0xff : 0); +} + + +static void m68k_op_smi_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_MI() ? 0xff : 0); +} + + +static void m68k_op_sge_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_GE() ? 0xff : 0); +} + + +static void m68k_op_sge_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_GE() ? 0xff : 0); +} + + +static void m68k_op_sge_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_GE() ? 0xff : 0); +} + + +static void m68k_op_sge_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_GE() ? 0xff : 0); +} + + +static void m68k_op_sge_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_GE() ? 0xff : 0); +} + + +static void m68k_op_sge_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_GE() ? 0xff : 0); +} + + +static void m68k_op_sge_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_GE() ? 0xff : 0); +} + + +static void m68k_op_sge_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_GE() ? 0xff : 0); +} + + +static void m68k_op_sge_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_GE() ? 0xff : 0); +} + + +static void m68k_op_slt_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_LT() ? 0xff : 0); +} + + +static void m68k_op_slt_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_LT() ? 0xff : 0); +} + + +static void m68k_op_slt_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_LT() ? 0xff : 0); +} + + +static void m68k_op_slt_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_LT() ? 0xff : 0); +} + + +static void m68k_op_slt_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_LT() ? 0xff : 0); +} + + +static void m68k_op_slt_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_LT() ? 0xff : 0); +} + + +static void m68k_op_slt_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_LT() ? 0xff : 0); +} + + +static void m68k_op_slt_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_LT() ? 0xff : 0); +} + + +static void m68k_op_slt_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_LT() ? 0xff : 0); +} + + +static void m68k_op_sgt_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_GT() ? 0xff : 0); +} + + +static void m68k_op_sgt_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_GT() ? 0xff : 0); +} + + +static void m68k_op_sgt_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_GT() ? 0xff : 0); +} + + +static void m68k_op_sgt_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_GT() ? 0xff : 0); +} + + +static void m68k_op_sgt_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_GT() ? 0xff : 0); +} + + +static void m68k_op_sgt_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_GT() ? 0xff : 0); +} + + +static void m68k_op_sgt_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_GT() ? 0xff : 0); +} + + +static void m68k_op_sgt_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_GT() ? 0xff : 0); +} + + +static void m68k_op_sgt_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_GT() ? 0xff : 0); +} + + +static void m68k_op_sle_8_ai(void) +{ + m68ki_write_8(EA_AY_AI_8(), COND_LE() ? 0xff : 0); +} + + +static void m68k_op_sle_8_pi(void) +{ + m68ki_write_8(EA_AY_PI_8(), COND_LE() ? 0xff : 0); +} + + +static void m68k_op_sle_8_pi7(void) +{ + m68ki_write_8(EA_A7_PI_8(), COND_LE() ? 0xff : 0); +} + + +static void m68k_op_sle_8_pd(void) +{ + m68ki_write_8(EA_AY_PD_8(), COND_LE() ? 0xff : 0); +} + + +static void m68k_op_sle_8_pd7(void) +{ + m68ki_write_8(EA_A7_PD_8(), COND_LE() ? 0xff : 0); +} + + +static void m68k_op_sle_8_di(void) +{ + m68ki_write_8(EA_AY_DI_8(), COND_LE() ? 0xff : 0); +} + + +static void m68k_op_sle_8_ix(void) +{ + m68ki_write_8(EA_AY_IX_8(), COND_LE() ? 0xff : 0); +} + + +static void m68k_op_sle_8_aw(void) +{ + m68ki_write_8(EA_AW_8(), COND_LE() ? 0xff : 0); +} + + +static void m68k_op_sle_8_al(void) +{ + m68ki_write_8(EA_AL_8(), COND_LE() ? 0xff : 0); +} + + +static void m68k_op_stop(void) +{ + if(FLAG_S) + { + uint new_sr = OPER_I_16(); + CPU_STOPPED |= STOP_LEVEL_STOP; + m68ki_set_sr(new_sr); + SET_CYCLES(m68ki_cpu.cycle_end - 4*MUL); + return; + } + m68ki_exception_privilege_violation(); +} + + +static void m68k_op_sub_8_er_d(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_8(DY); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_ai(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_AI_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_pi(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PI_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_pi7(void) +{ + uint* r_dst = &DX; + uint src = OPER_A7_PI_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_pd(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PD_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_pd7(void) +{ + uint* r_dst = &DX; + uint src = OPER_A7_PD_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_di(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_DI_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_ix(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_IX_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_aw(void) +{ + uint* r_dst = &DX; + uint src = OPER_AW_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_al(void) +{ + uint* r_dst = &DX; + uint src = OPER_AL_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_pcdi(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCDI_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_pcix(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCIX_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_8_er_i(void) +{ + uint* r_dst = &DX; + uint src = OPER_I_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_d(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(DY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_a(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(AY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_ai(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_AI_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_pi(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PI_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_pd(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PD_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_di(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_DI_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_ix(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_IX_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_aw(void) +{ + uint* r_dst = &DX; + uint src = OPER_AW_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_al(void) +{ + uint* r_dst = &DX; + uint src = OPER_AL_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_pcdi(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCDI_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_pcix(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCIX_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_16_er_i(void) +{ + uint* r_dst = &DX; + uint src = OPER_I_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_sub_32_er_d(void) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_32_er_a(void) +{ + uint* r_dst = &DX; + uint src = AY; + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_32_er_ai(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_AI_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_32_er_pi(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PI_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_32_er_pd(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_PD_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_32_er_di(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_DI_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_32_er_ix(void) +{ + uint* r_dst = &DX; + uint src = OPER_AY_IX_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_32_er_aw(void) +{ + uint* r_dst = &DX; + uint src = OPER_AW_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_32_er_al(void) +{ + uint* r_dst = &DX; + uint src = OPER_AL_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_32_er_pcdi(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCDI_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_32_er_pcix(void) +{ + uint* r_dst = &DX; + uint src = OPER_PCIX_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_32_er_i(void) +{ + uint* r_dst = &DX; + uint src = OPER_I_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_sub_8_re_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_sub_8_re_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_sub_8_re_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_sub_8_re_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_sub_8_re_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_sub_8_re_di(void) +{ + uint ea = EA_AY_DI_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_sub_8_re_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_sub_8_re_aw(void) +{ + uint ea = EA_AW_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_sub_8_re_al(void) +{ + uint ea = EA_AL_8(); + uint src = MASK_OUT_ABOVE_8(DX); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_sub_16_re_ai(void) +{ + uint ea = EA_AY_AI_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_sub_16_re_pi(void) +{ + uint ea = EA_AY_PI_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_sub_16_re_pd(void) +{ + uint ea = EA_AY_PD_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_sub_16_re_di(void) +{ + uint ea = EA_AY_DI_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_sub_16_re_ix(void) +{ + uint ea = EA_AY_IX_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_sub_16_re_aw(void) +{ + uint ea = EA_AW_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_sub_16_re_al(void) +{ + uint ea = EA_AL_16(); + uint src = MASK_OUT_ABOVE_16(DX); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_sub_32_re_ai(void) +{ + uint ea = EA_AY_AI_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_sub_32_re_pi(void) +{ + uint ea = EA_AY_PI_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_sub_32_re_pd(void) +{ + uint ea = EA_AY_PD_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_sub_32_re_di(void) +{ + uint ea = EA_AY_DI_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_sub_32_re_ix(void) +{ + uint ea = EA_AY_IX_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_sub_32_re_aw(void) +{ + uint ea = EA_AW_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_sub_32_re_al(void) +{ + uint ea = EA_AL_32(); + uint src = DX; + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_suba_16_d(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - MAKE_INT_16(DY)); +} + + +static void m68k_op_suba_16_a(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - MAKE_INT_16(AY)); +} + + +static void m68k_op_suba_16_ai(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AY_AI_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_16_pi(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AY_PI_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_16_pd(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AY_PD_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_16_di(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AY_DI_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_16_ix(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AY_IX_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_16_aw(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AW_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_16_al(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_AL_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_16_pcdi(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_PCDI_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_16_pcix(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_PCIX_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_16_i(void) +{ + uint* r_dst = &AX; + uint src = MAKE_INT_16(OPER_I_16()); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_32_d(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - DY); +} + + +static void m68k_op_suba_32_a(void) +{ + uint* r_dst = &AX; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - AY); +} + + +static void m68k_op_suba_32_ai(void) +{ + uint* r_dst = &AX; + uint src = OPER_AY_AI_32(); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_32_pi(void) +{ + uint* r_dst = &AX; + uint src = OPER_AY_PI_32(); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_32_pd(void) +{ + uint* r_dst = &AX; + uint src = OPER_AY_PD_32(); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_32_di(void) +{ + uint* r_dst = &AX; + uint src = OPER_AY_DI_32(); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_32_ix(void) +{ + uint* r_dst = &AX; + uint src = OPER_AY_IX_32(); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_32_aw(void) +{ + uint* r_dst = &AX; + uint src = OPER_AW_32(); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_32_al(void) +{ + uint* r_dst = &AX; + uint src = OPER_AL_32(); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_32_pcdi(void) +{ + uint* r_dst = &AX; + uint src = OPER_PCDI_32(); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_32_pcix(void) +{ + uint* r_dst = &AX; + uint src = OPER_PCIX_32(); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_suba_32_i(void) +{ + uint* r_dst = &AX; + uint src = OPER_I_32(); + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - src); +} + + +static void m68k_op_subi_8_d(void) +{ + uint* r_dst = &DY; + uint src = OPER_I_8(); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_subi_8_ai(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_AI_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subi_8_pi(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_PI_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subi_8_pi7(void) +{ + uint src = OPER_I_8(); + uint ea = EA_A7_PI_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subi_8_pd(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subi_8_pd7(void) +{ + uint src = OPER_I_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subi_8_di(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_DI_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subi_8_ix(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AY_IX_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subi_8_aw(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AW_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subi_8_al(void) +{ + uint src = OPER_I_8(); + uint ea = EA_AL_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subi_16_d(void) +{ + uint* r_dst = &DY; + uint src = OPER_I_16(); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_subi_16_ai(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_AI_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subi_16_pi(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_PI_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subi_16_pd(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_PD_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subi_16_di(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_DI_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subi_16_ix(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AY_IX_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subi_16_aw(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AW_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subi_16_al(void) +{ + uint src = OPER_I_16(); + uint ea = EA_AL_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subi_32_d(void) +{ + uint* r_dst = &DY; + uint src = OPER_I_32(); + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_subi_32_ai(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_AI_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subi_32_pi(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_PI_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subi_32_pd(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_PD_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subi_32_di(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_DI_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subi_32_ix(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AY_IX_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subi_32_aw(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AW_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subi_32_al(void) +{ + uint src = OPER_I_32(); + uint ea = EA_AL_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subq_8_d(void) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | FLAG_Z; +} + + +static void m68k_op_subq_8_ai(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_AI_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subq_8_pi(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PI_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subq_8_pi7(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_A7_PI_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subq_8_pd(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subq_8_pd7(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subq_8_di(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_DI_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subq_8_ix(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_IX_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subq_8_aw(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AW_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subq_8_al(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AL_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src; + + FLAG_N = NFLAG_8(res); + FLAG_Z = MASK_OUT_ABOVE_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + m68ki_write_8(ea, FLAG_Z); +} + + +static void m68k_op_subq_16_d(void) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | FLAG_Z; +} + + +static void m68k_op_subq_16_a(void) +{ + uint* r_dst = &AY; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - ((((REG_IR >> 9) - 1) & 7) + 1)); +} + + +static void m68k_op_subq_16_ai(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_AI_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subq_16_pi(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PI_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subq_16_pd(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PD_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subq_16_di(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_DI_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subq_16_ix(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_IX_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subq_16_aw(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AW_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subq_16_al(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AL_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src; + + FLAG_N = NFLAG_16(res); + FLAG_Z = MASK_OUT_ABOVE_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + m68ki_write_16(ea, FLAG_Z); +} + + +static void m68k_op_subq_32_d(void) +{ + uint* r_dst = &DY; + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint dst = *r_dst; + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + *r_dst = FLAG_Z; +} + + +static void m68k_op_subq_32_a(void) +{ + uint* r_dst = &AY; + + *r_dst = MASK_OUT_ABOVE_32(*r_dst - ((((REG_IR >> 9) - 1) & 7) + 1)); +} + + +static void m68k_op_subq_32_ai(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_AI_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subq_32_pi(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PI_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subq_32_pd(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_PD_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subq_32_di(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_DI_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subq_32_ix(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AY_IX_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subq_32_aw(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AW_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subq_32_al(void) +{ + uint src = (((REG_IR >> 9) - 1) & 7) + 1; + uint ea = EA_AL_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src; + + FLAG_N = NFLAG_32(res); + FLAG_Z = MASK_OUT_ABOVE_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + m68ki_write_32(ea, FLAG_Z); +} + + +static void m68k_op_subx_8_rr(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_8(DY); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; +} + + +static void m68k_op_subx_16_rr(void) +{ + uint* r_dst = &DX; + uint src = MASK_OUT_ABOVE_16(DY); + uint dst = MASK_OUT_ABOVE_16(*r_dst); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + *r_dst = MASK_OUT_BELOW_16(*r_dst) | res; +} + + +static void m68k_op_subx_32_rr(void) +{ + uint* r_dst = &DX; + uint src = DY; + uint dst = *r_dst; + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + *r_dst = res; +} + + +static void m68k_op_subx_8_mm_ax7(void) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_subx_8_mm_ay7(void) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_subx_8_mm_axy7(void) +{ + uint src = OPER_A7_PD_8(); + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_subx_8_mm(void) +{ + uint src = OPER_AY_PD_8(); + uint ea = EA_AX_PD_8(); + uint dst = m68ki_read_8(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_8(res); + FLAG_X = FLAG_C = CFLAG_8(res); + FLAG_V = VFLAG_SUB_8(src, dst, res); + + res = MASK_OUT_ABOVE_8(res); + FLAG_Z |= res; + + m68ki_write_8(ea, res); +} + + +static void m68k_op_subx_16_mm(void) +{ + uint src = OPER_AY_PD_16(); + uint ea = EA_AX_PD_16(); + uint dst = m68ki_read_16(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_16(res); + FLAG_X = FLAG_C = CFLAG_16(res); + FLAG_V = VFLAG_SUB_16(src, dst, res); + + res = MASK_OUT_ABOVE_16(res); + FLAG_Z |= res; + + m68ki_write_16(ea, res); +} + + +static void m68k_op_subx_32_mm(void) +{ + uint src = OPER_AY_PD_32(); + uint ea = EA_AX_PD_32(); + uint dst = m68ki_read_32(ea); + uint res = dst - src - XFLAG_AS_1(); + + FLAG_N = NFLAG_32(res); + FLAG_X = FLAG_C = CFLAG_SUB_32(src, dst, res); + FLAG_V = VFLAG_SUB_32(src, dst, res); + + res = MASK_OUT_ABOVE_32(res); + FLAG_Z |= res; + + m68ki_write_32(ea, res); +} + + +static void m68k_op_swap_32(void) +{ + uint* r_dst = &DY; + + FLAG_Z = MASK_OUT_ABOVE_32(*r_dst<<16); + *r_dst = (*r_dst>>16) | FLAG_Z; + + FLAG_Z = *r_dst; + FLAG_N = NFLAG_32(*r_dst); + FLAG_C = CFLAG_CLEAR; + FLAG_V = VFLAG_CLEAR; +} + + +static void m68k_op_tas_8_d(void) +{ + uint* r_dst = &DY; + + FLAG_Z = MASK_OUT_ABOVE_8(*r_dst); + FLAG_N = NFLAG_8(*r_dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + *r_dst |= 0x80; +} + + +static void m68k_op_tas_8_ai(void) +{ + uint ea = EA_AY_AI_8(); + uint dst = m68ki_read_8(ea); + + FLAG_Z = dst; + FLAG_N = NFLAG_8(dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback + disabled in order to function properly. Some Amiga software may also rely + on this, but only when accessing specific addresses so additional functionality + will be needed. */ + if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80); +} + + +static void m68k_op_tas_8_pi(void) +{ + uint ea = EA_AY_PI_8(); + uint dst = m68ki_read_8(ea); + + FLAG_Z = dst; + FLAG_N = NFLAG_8(dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback + disabled in order to function properly. Some Amiga software may also rely + on this, but only when accessing specific addresses so additional functionality + will be needed. */ + if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80); +} + + +static void m68k_op_tas_8_pi7(void) +{ + uint ea = EA_A7_PI_8(); + uint dst = m68ki_read_8(ea); + + FLAG_Z = dst; + FLAG_N = NFLAG_8(dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback + disabled in order to function properly. Some Amiga software may also rely + on this, but only when accessing specific addresses so additional functionality + will be needed. */ + if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80); +} + + +static void m68k_op_tas_8_pd(void) +{ + uint ea = EA_AY_PD_8(); + uint dst = m68ki_read_8(ea); + + FLAG_Z = dst; + FLAG_N = NFLAG_8(dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback + disabled in order to function properly. Some Amiga software may also rely + on this, but only when accessing specific addresses so additional functionality + will be needed. */ + if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80); +} + + +static void m68k_op_tas_8_pd7(void) +{ + uint ea = EA_A7_PD_8(); + uint dst = m68ki_read_8(ea); + + FLAG_Z = dst; + FLAG_N = NFLAG_8(dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback + disabled in order to function properly. Some Amiga software may also rely + on this, but only when accessing specific addresses so additional functionality + will be needed. */ + if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80); +} + + +static void m68k_op_tas_8_di(void) +{ + uint ea = EA_AY_DI_8(); + uint dst = m68ki_read_8(ea); + + FLAG_Z = dst; + FLAG_N = NFLAG_8(dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback + disabled in order to function properly. Some Amiga software may also rely + on this, but only when accessing specific addresses so additional functionality + will be needed. */ + if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80); +} + + +static void m68k_op_tas_8_ix(void) +{ + uint ea = EA_AY_IX_8(); + uint dst = m68ki_read_8(ea); + + FLAG_Z = dst; + FLAG_N = NFLAG_8(dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback + disabled in order to function properly. Some Amiga software may also rely + on this, but only when accessing specific addresses so additional functionality + will be needed. */ + if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80); +} + + +static void m68k_op_tas_8_aw(void) +{ + uint ea = EA_AW_8(); + uint dst = m68ki_read_8(ea); + + FLAG_Z = dst; + FLAG_N = NFLAG_8(dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback + disabled in order to function properly. Some Amiga software may also rely + on this, but only when accessing specific addresses so additional functionality + will be needed. */ + if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80); +} + + +static void m68k_op_tas_8_al(void) +{ + uint ea = EA_AL_8(); + uint dst = m68ki_read_8(ea); + + FLAG_Z = dst; + FLAG_N = NFLAG_8(dst); + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; + + /* The Genesis/Megadrive games Gargoyles and Ex-Mutants need the TAS writeback + disabled in order to function properly. Some Amiga software may also rely + on this, but only when accessing specific addresses so additional functionality + will be needed. */ + if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80); +} + + +static void m68k_op_trap(void) +{ + /* Trap#n stacks exception frame type 0 */ + m68ki_exception_trapN(EXCEPTION_TRAP_BASE + (REG_IR & 0xf)); /* HJB 990403 */ +} + + +static void m68k_op_trapv(void) +{ + if(COND_VC()) + { + return; + } + m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ +} + + +static void m68k_op_tst_8_d(void) +{ + uint res = MASK_OUT_ABOVE_8(DY); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_8_ai(void) +{ + uint res = OPER_AY_AI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_8_pi(void) +{ + uint res = OPER_AY_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_8_pi7(void) +{ + uint res = OPER_A7_PI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_8_pd(void) +{ + uint res = OPER_AY_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_8_pd7(void) +{ + uint res = OPER_A7_PD_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_8_di(void) +{ + uint res = OPER_AY_DI_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_8_ix(void) +{ + uint res = OPER_AY_IX_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_8_aw(void) +{ + uint res = OPER_AW_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_8_al(void) +{ + uint res = OPER_AL_8(); + + FLAG_N = NFLAG_8(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_16_d(void) +{ + uint res = MASK_OUT_ABOVE_16(DY); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_16_ai(void) +{ + uint res = OPER_AY_AI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_16_pi(void) +{ + uint res = OPER_AY_PI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_16_pd(void) +{ + uint res = OPER_AY_PD_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_16_di(void) +{ + uint res = OPER_AY_DI_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_16_ix(void) +{ + uint res = OPER_AY_IX_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_16_aw(void) +{ + uint res = OPER_AW_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_16_al(void) +{ + uint res = OPER_AL_16(); + + FLAG_N = NFLAG_16(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_32_d(void) +{ + uint res = DY; + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_32_ai(void) +{ + uint res = OPER_AY_AI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_32_pi(void) +{ + uint res = OPER_AY_PI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_32_pd(void) +{ + uint res = OPER_AY_PD_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_32_di(void) +{ + uint res = OPER_AY_DI_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_32_ix(void) +{ + uint res = OPER_AY_IX_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_32_aw(void) +{ + uint res = OPER_AW_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_tst_32_al(void) +{ + uint res = OPER_AL_32(); + + FLAG_N = NFLAG_32(res); + FLAG_Z = res; + FLAG_V = VFLAG_CLEAR; + FLAG_C = CFLAG_CLEAR; +} + + +static void m68k_op_unlk_32_a7(void) +{ + REG_A[7] = m68ki_read_32(REG_A[7]); +} + + +static void m68k_op_unlk_32(void) +{ + uint* r_dst = &AY; + + REG_A[7] = *r_dst; + *r_dst = m68ki_pull_32(); +} + + +/* ======================================================================== */ +/* ========================= OPCODE TABLE BUILDER ========================= */ +/* ======================================================================== */ + +#ifndef BUILD_TABLES + +#include "m68ki_instruction_jump_table.h" + +#else + +/* This is used to generate the opcode handler jump table */ +typedef struct +{ + void (*opcode_handler)(void); /* handler function */ + unsigned int mask; /* mask on opcode */ + unsigned int match; /* what to match after masking */ + unsigned char cycles; /* cycles each cpu type takes */ +} opcode_handler_struct; + +/* opcode handler jump table */ +static void (*m68ki_instruction_jump_table[0x10000])(void); + +/* Opcode handler table */ +static const opcode_handler_struct m68k_opcode_handler_table[] = +{ +/* function mask match cyc */ + {m68k_op_1010 , 0xf000, 0xa000, 4}, + {m68k_op_1111 , 0xf000, 0xf000, 4}, + {m68k_op_moveq_32 , 0xf100, 0x7000, 4}, + {m68k_op_bra_8 , 0xff00, 0x6000, 10}, + {m68k_op_bsr_8 , 0xff00, 0x6100, 18}, + {m68k_op_bhi_8 , 0xff00, 0x6200, 10}, + {m68k_op_bls_8 , 0xff00, 0x6300, 10}, + {m68k_op_bcc_8 , 0xff00, 0x6400, 10}, + {m68k_op_bcs_8 , 0xff00, 0x6500, 10}, + {m68k_op_bne_8 , 0xff00, 0x6600, 10}, + {m68k_op_beq_8 , 0xff00, 0x6700, 10}, + {m68k_op_bvc_8 , 0xff00, 0x6800, 10}, + {m68k_op_bvs_8 , 0xff00, 0x6900, 10}, + {m68k_op_bpl_8 , 0xff00, 0x6a00, 10}, + {m68k_op_bmi_8 , 0xff00, 0x6b00, 10}, + {m68k_op_bge_8 , 0xff00, 0x6c00, 10}, + {m68k_op_blt_8 , 0xff00, 0x6d00, 10}, + {m68k_op_bgt_8 , 0xff00, 0x6e00, 10}, + {m68k_op_ble_8 , 0xff00, 0x6f00, 10}, + {m68k_op_btst_32_r_d , 0xf1f8, 0x0100, 6}, + {m68k_op_movep_16_er , 0xf1f8, 0x0108, 16}, + {m68k_op_btst_8_r_ai , 0xf1f8, 0x0110, 8}, + {m68k_op_btst_8_r_pi , 0xf1f8, 0x0118, 8}, + {m68k_op_btst_8_r_pd , 0xf1f8, 0x0120, 10}, + {m68k_op_btst_8_r_di , 0xf1f8, 0x0128, 12}, + {m68k_op_btst_8_r_ix , 0xf1f8, 0x0130, 14}, + {m68k_op_bchg_32_r_d , 0xf1f8, 0x0140, 8}, + {m68k_op_movep_32_er , 0xf1f8, 0x0148, 24}, + {m68k_op_bchg_8_r_ai , 0xf1f8, 0x0150, 12}, + {m68k_op_bchg_8_r_pi , 0xf1f8, 0x0158, 12}, + {m68k_op_bchg_8_r_pd , 0xf1f8, 0x0160, 14}, + {m68k_op_bchg_8_r_di , 0xf1f8, 0x0168, 16}, + {m68k_op_bchg_8_r_ix , 0xf1f8, 0x0170, 18}, + {m68k_op_bclr_32_r_d , 0xf1f8, 0x0180, 10}, + {m68k_op_movep_16_re , 0xf1f8, 0x0188, 16}, + {m68k_op_bclr_8_r_ai , 0xf1f8, 0x0190, 12}, + {m68k_op_bclr_8_r_pi , 0xf1f8, 0x0198, 12}, + {m68k_op_bclr_8_r_pd , 0xf1f8, 0x01a0, 14}, + {m68k_op_bclr_8_r_di , 0xf1f8, 0x01a8, 16}, + {m68k_op_bclr_8_r_ix , 0xf1f8, 0x01b0, 18}, + {m68k_op_bset_32_r_d , 0xf1f8, 0x01c0, 8}, + {m68k_op_movep_32_re , 0xf1f8, 0x01c8, 24}, + {m68k_op_bset_8_r_ai , 0xf1f8, 0x01d0, 12}, + {m68k_op_bset_8_r_pi , 0xf1f8, 0x01d8, 12}, + {m68k_op_bset_8_r_pd , 0xf1f8, 0x01e0, 14}, + {m68k_op_bset_8_r_di , 0xf1f8, 0x01e8, 16}, + {m68k_op_bset_8_r_ix , 0xf1f8, 0x01f0, 18}, + {m68k_op_move_8_d_d , 0xf1f8, 0x1000, 4}, + {m68k_op_move_8_d_ai , 0xf1f8, 0x1010, 8}, + {m68k_op_move_8_d_pi , 0xf1f8, 0x1018, 8}, + {m68k_op_move_8_d_pd , 0xf1f8, 0x1020, 10}, + {m68k_op_move_8_d_di , 0xf1f8, 0x1028, 12}, + {m68k_op_move_8_d_ix , 0xf1f8, 0x1030, 14}, + {m68k_op_move_8_ai_d , 0xf1f8, 0x1080, 8}, + {m68k_op_move_8_ai_ai , 0xf1f8, 0x1090, 12}, + {m68k_op_move_8_ai_pi , 0xf1f8, 0x1098, 12}, + {m68k_op_move_8_ai_pd , 0xf1f8, 0x10a0, 14}, + {m68k_op_move_8_ai_di , 0xf1f8, 0x10a8, 16}, + {m68k_op_move_8_ai_ix , 0xf1f8, 0x10b0, 18}, + {m68k_op_move_8_pi_d , 0xf1f8, 0x10c0, 8}, + {m68k_op_move_8_pi_ai , 0xf1f8, 0x10d0, 12}, + {m68k_op_move_8_pi_pi , 0xf1f8, 0x10d8, 12}, + {m68k_op_move_8_pi_pd , 0xf1f8, 0x10e0, 14}, + {m68k_op_move_8_pi_di , 0xf1f8, 0x10e8, 16}, + {m68k_op_move_8_pi_ix , 0xf1f8, 0x10f0, 18}, + {m68k_op_move_8_pd_d , 0xf1f8, 0x1100, 8}, + {m68k_op_move_8_pd_ai , 0xf1f8, 0x1110, 12}, + {m68k_op_move_8_pd_pi , 0xf1f8, 0x1118, 12}, + {m68k_op_move_8_pd_pd , 0xf1f8, 0x1120, 14}, + {m68k_op_move_8_pd_di , 0xf1f8, 0x1128, 16}, + {m68k_op_move_8_pd_ix , 0xf1f8, 0x1130, 18}, + {m68k_op_move_8_di_d , 0xf1f8, 0x1140, 12}, + {m68k_op_move_8_di_ai , 0xf1f8, 0x1150, 16}, + {m68k_op_move_8_di_pi , 0xf1f8, 0x1158, 16}, + {m68k_op_move_8_di_pd , 0xf1f8, 0x1160, 18}, + {m68k_op_move_8_di_di , 0xf1f8, 0x1168, 20}, + {m68k_op_move_8_di_ix , 0xf1f8, 0x1170, 22}, + {m68k_op_move_8_ix_d , 0xf1f8, 0x1180, 14}, + {m68k_op_move_8_ix_ai , 0xf1f8, 0x1190, 18}, + {m68k_op_move_8_ix_pi , 0xf1f8, 0x1198, 18}, + {m68k_op_move_8_ix_pd , 0xf1f8, 0x11a0, 20}, + {m68k_op_move_8_ix_di , 0xf1f8, 0x11a8, 22}, + {m68k_op_move_8_ix_ix , 0xf1f8, 0x11b0, 24}, + {m68k_op_move_32_d_d , 0xf1f8, 0x2000, 4}, + {m68k_op_move_32_d_a , 0xf1f8, 0x2008, 4}, + {m68k_op_move_32_d_ai , 0xf1f8, 0x2010, 12}, + {m68k_op_move_32_d_pi , 0xf1f8, 0x2018, 12}, + {m68k_op_move_32_d_pd , 0xf1f8, 0x2020, 14}, + {m68k_op_move_32_d_di , 0xf1f8, 0x2028, 16}, + {m68k_op_move_32_d_ix , 0xf1f8, 0x2030, 18}, + {m68k_op_movea_32_d , 0xf1f8, 0x2040, 4}, + {m68k_op_movea_32_a , 0xf1f8, 0x2048, 4}, + {m68k_op_movea_32_ai , 0xf1f8, 0x2050, 12}, + {m68k_op_movea_32_pi , 0xf1f8, 0x2058, 12}, + {m68k_op_movea_32_pd , 0xf1f8, 0x2060, 14}, + {m68k_op_movea_32_di , 0xf1f8, 0x2068, 16}, + {m68k_op_movea_32_ix , 0xf1f8, 0x2070, 18}, + {m68k_op_move_32_ai_d , 0xf1f8, 0x2080, 12}, + {m68k_op_move_32_ai_a , 0xf1f8, 0x2088, 12}, + {m68k_op_move_32_ai_ai , 0xf1f8, 0x2090, 20}, + {m68k_op_move_32_ai_pi , 0xf1f8, 0x2098, 20}, + {m68k_op_move_32_ai_pd , 0xf1f8, 0x20a0, 22}, + {m68k_op_move_32_ai_di , 0xf1f8, 0x20a8, 24}, + {m68k_op_move_32_ai_ix , 0xf1f8, 0x20b0, 26}, + {m68k_op_move_32_pi_d , 0xf1f8, 0x20c0, 12}, + {m68k_op_move_32_pi_a , 0xf1f8, 0x20c8, 12}, + {m68k_op_move_32_pi_ai , 0xf1f8, 0x20d0, 20}, + {m68k_op_move_32_pi_pi , 0xf1f8, 0x20d8, 20}, + {m68k_op_move_32_pi_pd , 0xf1f8, 0x20e0, 22}, + {m68k_op_move_32_pi_di , 0xf1f8, 0x20e8, 24}, + {m68k_op_move_32_pi_ix , 0xf1f8, 0x20f0, 26}, + {m68k_op_move_32_pd_d , 0xf1f8, 0x2100, 12}, + {m68k_op_move_32_pd_a , 0xf1f8, 0x2108, 12}, + {m68k_op_move_32_pd_ai , 0xf1f8, 0x2110, 20}, + {m68k_op_move_32_pd_pi , 0xf1f8, 0x2118, 20}, + {m68k_op_move_32_pd_pd , 0xf1f8, 0x2120, 22}, + {m68k_op_move_32_pd_di , 0xf1f8, 0x2128, 24}, + {m68k_op_move_32_pd_ix , 0xf1f8, 0x2130, 26}, + {m68k_op_move_32_di_d , 0xf1f8, 0x2140, 16}, + {m68k_op_move_32_di_a , 0xf1f8, 0x2148, 16}, + {m68k_op_move_32_di_ai , 0xf1f8, 0x2150, 24}, + {m68k_op_move_32_di_pi , 0xf1f8, 0x2158, 24}, + {m68k_op_move_32_di_pd , 0xf1f8, 0x2160, 26}, + {m68k_op_move_32_di_di , 0xf1f8, 0x2168, 28}, + {m68k_op_move_32_di_ix , 0xf1f8, 0x2170, 30}, + {m68k_op_move_32_ix_d , 0xf1f8, 0x2180, 18}, + {m68k_op_move_32_ix_a , 0xf1f8, 0x2188, 18}, + {m68k_op_move_32_ix_ai , 0xf1f8, 0x2190, 26}, + {m68k_op_move_32_ix_pi , 0xf1f8, 0x2198, 26}, + {m68k_op_move_32_ix_pd , 0xf1f8, 0x21a0, 28}, + {m68k_op_move_32_ix_di , 0xf1f8, 0x21a8, 30}, + {m68k_op_move_32_ix_ix , 0xf1f8, 0x21b0, 32}, + {m68k_op_move_16_d_d , 0xf1f8, 0x3000, 4}, + {m68k_op_move_16_d_a , 0xf1f8, 0x3008, 4}, + {m68k_op_move_16_d_ai , 0xf1f8, 0x3010, 8}, + {m68k_op_move_16_d_pi , 0xf1f8, 0x3018, 8}, + {m68k_op_move_16_d_pd , 0xf1f8, 0x3020, 10}, + {m68k_op_move_16_d_di , 0xf1f8, 0x3028, 12}, + {m68k_op_move_16_d_ix , 0xf1f8, 0x3030, 14}, + {m68k_op_movea_16_d , 0xf1f8, 0x3040, 4}, + {m68k_op_movea_16_a , 0xf1f8, 0x3048, 4}, + {m68k_op_movea_16_ai , 0xf1f8, 0x3050, 8}, + {m68k_op_movea_16_pi , 0xf1f8, 0x3058, 8}, + {m68k_op_movea_16_pd , 0xf1f8, 0x3060, 10}, + {m68k_op_movea_16_di , 0xf1f8, 0x3068, 12}, + {m68k_op_movea_16_ix , 0xf1f8, 0x3070, 14}, + {m68k_op_move_16_ai_d , 0xf1f8, 0x3080, 8}, + {m68k_op_move_16_ai_a , 0xf1f8, 0x3088, 8}, + {m68k_op_move_16_ai_ai , 0xf1f8, 0x3090, 12}, + {m68k_op_move_16_ai_pi , 0xf1f8, 0x3098, 12}, + {m68k_op_move_16_ai_pd , 0xf1f8, 0x30a0, 14}, + {m68k_op_move_16_ai_di , 0xf1f8, 0x30a8, 16}, + {m68k_op_move_16_ai_ix , 0xf1f8, 0x30b0, 18}, + {m68k_op_move_16_pi_d , 0xf1f8, 0x30c0, 8}, + {m68k_op_move_16_pi_a , 0xf1f8, 0x30c8, 8}, + {m68k_op_move_16_pi_ai , 0xf1f8, 0x30d0, 12}, + {m68k_op_move_16_pi_pi , 0xf1f8, 0x30d8, 12}, + {m68k_op_move_16_pi_pd , 0xf1f8, 0x30e0, 14}, + {m68k_op_move_16_pi_di , 0xf1f8, 0x30e8, 16}, + {m68k_op_move_16_pi_ix , 0xf1f8, 0x30f0, 18}, + {m68k_op_move_16_pd_d , 0xf1f8, 0x3100, 8}, + {m68k_op_move_16_pd_a , 0xf1f8, 0x3108, 8}, + {m68k_op_move_16_pd_ai , 0xf1f8, 0x3110, 12}, + {m68k_op_move_16_pd_pi , 0xf1f8, 0x3118, 12}, + {m68k_op_move_16_pd_pd , 0xf1f8, 0x3120, 14}, + {m68k_op_move_16_pd_di , 0xf1f8, 0x3128, 16}, + {m68k_op_move_16_pd_ix , 0xf1f8, 0x3130, 18}, + {m68k_op_move_16_di_d , 0xf1f8, 0x3140, 12}, + {m68k_op_move_16_di_a , 0xf1f8, 0x3148, 12}, + {m68k_op_move_16_di_ai , 0xf1f8, 0x3150, 16}, + {m68k_op_move_16_di_pi , 0xf1f8, 0x3158, 16}, + {m68k_op_move_16_di_pd , 0xf1f8, 0x3160, 18}, + {m68k_op_move_16_di_di , 0xf1f8, 0x3168, 20}, + {m68k_op_move_16_di_ix , 0xf1f8, 0x3170, 22}, + {m68k_op_move_16_ix_d , 0xf1f8, 0x3180, 14}, + {m68k_op_move_16_ix_a , 0xf1f8, 0x3188, 14}, + {m68k_op_move_16_ix_ai , 0xf1f8, 0x3190, 18}, + {m68k_op_move_16_ix_pi , 0xf1f8, 0x3198, 18}, + {m68k_op_move_16_ix_pd , 0xf1f8, 0x31a0, 20}, + {m68k_op_move_16_ix_di , 0xf1f8, 0x31a8, 22}, + {m68k_op_move_16_ix_ix , 0xf1f8, 0x31b0, 24}, + {m68k_op_chk_16_d , 0xf1f8, 0x4180, 10}, + {m68k_op_chk_16_ai , 0xf1f8, 0x4190, 14}, + {m68k_op_chk_16_pi , 0xf1f8, 0x4198, 14}, + {m68k_op_chk_16_pd , 0xf1f8, 0x41a0, 16}, + {m68k_op_chk_16_di , 0xf1f8, 0x41a8, 18}, + {m68k_op_chk_16_ix , 0xf1f8, 0x41b0, 20}, + {m68k_op_lea_32_ai , 0xf1f8, 0x41d0, 4}, + {m68k_op_lea_32_di , 0xf1f8, 0x41e8, 8}, + {m68k_op_lea_32_ix , 0xf1f8, 0x41f0, 12}, + {m68k_op_addq_8_d , 0xf1f8, 0x5000, 4}, + {m68k_op_addq_8_ai , 0xf1f8, 0x5010, 12}, + {m68k_op_addq_8_pi , 0xf1f8, 0x5018, 12}, + {m68k_op_addq_8_pd , 0xf1f8, 0x5020, 14}, + {m68k_op_addq_8_di , 0xf1f8, 0x5028, 16}, + {m68k_op_addq_8_ix , 0xf1f8, 0x5030, 18}, + {m68k_op_addq_16_d , 0xf1f8, 0x5040, 4}, + {m68k_op_addq_16_a , 0xf1f8, 0x5048, 4}, + {m68k_op_addq_16_ai , 0xf1f8, 0x5050, 12}, + {m68k_op_addq_16_pi , 0xf1f8, 0x5058, 12}, + {m68k_op_addq_16_pd , 0xf1f8, 0x5060, 14}, + {m68k_op_addq_16_di , 0xf1f8, 0x5068, 16}, + {m68k_op_addq_16_ix , 0xf1f8, 0x5070, 18}, + {m68k_op_addq_32_d , 0xf1f8, 0x5080, 8}, + {m68k_op_addq_32_a , 0xf1f8, 0x5088, 8}, + {m68k_op_addq_32_ai , 0xf1f8, 0x5090, 20}, + {m68k_op_addq_32_pi , 0xf1f8, 0x5098, 20}, + {m68k_op_addq_32_pd , 0xf1f8, 0x50a0, 22}, + {m68k_op_addq_32_di , 0xf1f8, 0x50a8, 24}, + {m68k_op_addq_32_ix , 0xf1f8, 0x50b0, 26}, + {m68k_op_subq_8_d , 0xf1f8, 0x5100, 4}, + {m68k_op_subq_8_ai , 0xf1f8, 0x5110, 12}, + {m68k_op_subq_8_pi , 0xf1f8, 0x5118, 12}, + {m68k_op_subq_8_pd , 0xf1f8, 0x5120, 14}, + {m68k_op_subq_8_di , 0xf1f8, 0x5128, 16}, + {m68k_op_subq_8_ix , 0xf1f8, 0x5130, 18}, + {m68k_op_subq_16_d , 0xf1f8, 0x5140, 4}, + {m68k_op_subq_16_a , 0xf1f8, 0x5148, 8}, + {m68k_op_subq_16_ai , 0xf1f8, 0x5150, 12}, + {m68k_op_subq_16_pi , 0xf1f8, 0x5158, 12}, + {m68k_op_subq_16_pd , 0xf1f8, 0x5160, 14}, + {m68k_op_subq_16_di , 0xf1f8, 0x5168, 16}, + {m68k_op_subq_16_ix , 0xf1f8, 0x5170, 18}, + {m68k_op_subq_32_d , 0xf1f8, 0x5180, 8}, + {m68k_op_subq_32_a , 0xf1f8, 0x5188, 8}, + {m68k_op_subq_32_ai , 0xf1f8, 0x5190, 20}, + {m68k_op_subq_32_pi , 0xf1f8, 0x5198, 20}, + {m68k_op_subq_32_pd , 0xf1f8, 0x51a0, 22}, + {m68k_op_subq_32_di , 0xf1f8, 0x51a8, 24}, + {m68k_op_subq_32_ix , 0xf1f8, 0x51b0, 26}, + {m68k_op_or_8_er_d , 0xf1f8, 0x8000, 4}, + {m68k_op_or_8_er_ai , 0xf1f8, 0x8010, 8}, + {m68k_op_or_8_er_pi , 0xf1f8, 0x8018, 8}, + {m68k_op_or_8_er_pd , 0xf1f8, 0x8020, 10}, + {m68k_op_or_8_er_di , 0xf1f8, 0x8028, 12}, + {m68k_op_or_8_er_ix , 0xf1f8, 0x8030, 14}, + {m68k_op_or_16_er_d , 0xf1f8, 0x8040, 4}, + {m68k_op_or_16_er_ai , 0xf1f8, 0x8050, 8}, + {m68k_op_or_16_er_pi , 0xf1f8, 0x8058, 8}, + {m68k_op_or_16_er_pd , 0xf1f8, 0x8060, 10}, + {m68k_op_or_16_er_di , 0xf1f8, 0x8068, 12}, + {m68k_op_or_16_er_ix , 0xf1f8, 0x8070, 14}, + {m68k_op_or_32_er_d , 0xf1f8, 0x8080, 8}, + {m68k_op_or_32_er_ai , 0xf1f8, 0x8090, 14}, + {m68k_op_or_32_er_pi , 0xf1f8, 0x8098, 14}, + {m68k_op_or_32_er_pd , 0xf1f8, 0x80a0, 16}, + {m68k_op_or_32_er_di , 0xf1f8, 0x80a8, 18}, + {m68k_op_or_32_er_ix , 0xf1f8, 0x80b0, 20}, + {m68k_op_divu_16_d , 0xf1f8, 0x80c0, 0}, + {m68k_op_divu_16_ai , 0xf1f8, 0x80d0, 4}, + {m68k_op_divu_16_pi , 0xf1f8, 0x80d8, 4}, + {m68k_op_divu_16_pd , 0xf1f8, 0x80e0, 6}, + {m68k_op_divu_16_di , 0xf1f8, 0x80e8, 8}, + {m68k_op_divu_16_ix , 0xf1f8, 0x80f0, 10}, + {m68k_op_sbcd_8_rr , 0xf1f8, 0x8100, 6}, + {m68k_op_sbcd_8_mm , 0xf1f8, 0x8108, 18}, + {m68k_op_or_8_re_ai , 0xf1f8, 0x8110, 12}, + {m68k_op_or_8_re_pi , 0xf1f8, 0x8118, 12}, + {m68k_op_or_8_re_pd , 0xf1f8, 0x8120, 14}, + {m68k_op_or_8_re_di , 0xf1f8, 0x8128, 16}, + {m68k_op_or_8_re_ix , 0xf1f8, 0x8130, 18}, + {m68k_op_or_16_re_ai , 0xf1f8, 0x8150, 12}, + {m68k_op_or_16_re_pi , 0xf1f8, 0x8158, 12}, + {m68k_op_or_16_re_pd , 0xf1f8, 0x8160, 14}, + {m68k_op_or_16_re_di , 0xf1f8, 0x8168, 16}, + {m68k_op_or_16_re_ix , 0xf1f8, 0x8170, 18}, + {m68k_op_or_32_re_ai , 0xf1f8, 0x8190, 20}, + {m68k_op_or_32_re_pi , 0xf1f8, 0x8198, 20}, + {m68k_op_or_32_re_pd , 0xf1f8, 0x81a0, 22}, + {m68k_op_or_32_re_di , 0xf1f8, 0x81a8, 24}, + {m68k_op_or_32_re_ix , 0xf1f8, 0x81b0, 26}, + {m68k_op_divs_16_d , 0xf1f8, 0x81c0, 0}, + {m68k_op_divs_16_ai , 0xf1f8, 0x81d0, 4}, + {m68k_op_divs_16_pi , 0xf1f8, 0x81d8, 4}, + {m68k_op_divs_16_pd , 0xf1f8, 0x81e0, 6}, + {m68k_op_divs_16_di , 0xf1f8, 0x81e8, 8}, + {m68k_op_divs_16_ix , 0xf1f8, 0x81f0, 10}, + {m68k_op_sub_8_er_d , 0xf1f8, 0x9000, 4}, + {m68k_op_sub_8_er_ai , 0xf1f8, 0x9010, 8}, + {m68k_op_sub_8_er_pi , 0xf1f8, 0x9018, 8}, + {m68k_op_sub_8_er_pd , 0xf1f8, 0x9020, 10}, + {m68k_op_sub_8_er_di , 0xf1f8, 0x9028, 12}, + {m68k_op_sub_8_er_ix , 0xf1f8, 0x9030, 14}, + {m68k_op_sub_16_er_d , 0xf1f8, 0x9040, 4}, + {m68k_op_sub_16_er_a , 0xf1f8, 0x9048, 4}, + {m68k_op_sub_16_er_ai , 0xf1f8, 0x9050, 8}, + {m68k_op_sub_16_er_pi , 0xf1f8, 0x9058, 8}, + {m68k_op_sub_16_er_pd , 0xf1f8, 0x9060, 10}, + {m68k_op_sub_16_er_di , 0xf1f8, 0x9068, 12}, + {m68k_op_sub_16_er_ix , 0xf1f8, 0x9070, 14}, + {m68k_op_sub_32_er_d , 0xf1f8, 0x9080, 8}, + {m68k_op_sub_32_er_a , 0xf1f8, 0x9088, 8}, + {m68k_op_sub_32_er_ai , 0xf1f8, 0x9090, 14}, + {m68k_op_sub_32_er_pi , 0xf1f8, 0x9098, 14}, + {m68k_op_sub_32_er_pd , 0xf1f8, 0x90a0, 16}, + {m68k_op_sub_32_er_di , 0xf1f8, 0x90a8, 18}, + {m68k_op_sub_32_er_ix , 0xf1f8, 0x90b0, 20}, + {m68k_op_suba_16_d , 0xf1f8, 0x90c0, 8}, + {m68k_op_suba_16_a , 0xf1f8, 0x90c8, 8}, + {m68k_op_suba_16_ai , 0xf1f8, 0x90d0, 12}, + {m68k_op_suba_16_pi , 0xf1f8, 0x90d8, 12}, + {m68k_op_suba_16_pd , 0xf1f8, 0x90e0, 14}, + {m68k_op_suba_16_di , 0xf1f8, 0x90e8, 16}, + {m68k_op_suba_16_ix , 0xf1f8, 0x90f0, 18}, + {m68k_op_subx_8_rr , 0xf1f8, 0x9100, 4}, + {m68k_op_subx_8_mm , 0xf1f8, 0x9108, 18}, + {m68k_op_sub_8_re_ai , 0xf1f8, 0x9110, 12}, + {m68k_op_sub_8_re_pi , 0xf1f8, 0x9118, 12}, + {m68k_op_sub_8_re_pd , 0xf1f8, 0x9120, 14}, + {m68k_op_sub_8_re_di , 0xf1f8, 0x9128, 16}, + {m68k_op_sub_8_re_ix , 0xf1f8, 0x9130, 18}, + {m68k_op_subx_16_rr , 0xf1f8, 0x9140, 4}, + {m68k_op_subx_16_mm , 0xf1f8, 0x9148, 18}, + {m68k_op_sub_16_re_ai , 0xf1f8, 0x9150, 12}, + {m68k_op_sub_16_re_pi , 0xf1f8, 0x9158, 12}, + {m68k_op_sub_16_re_pd , 0xf1f8, 0x9160, 14}, + {m68k_op_sub_16_re_di , 0xf1f8, 0x9168, 16}, + {m68k_op_sub_16_re_ix , 0xf1f8, 0x9170, 18}, + {m68k_op_subx_32_rr , 0xf1f8, 0x9180, 8}, + {m68k_op_subx_32_mm , 0xf1f8, 0x9188, 30}, + {m68k_op_sub_32_re_ai , 0xf1f8, 0x9190, 20}, + {m68k_op_sub_32_re_pi , 0xf1f8, 0x9198, 20}, + {m68k_op_sub_32_re_pd , 0xf1f8, 0x91a0, 22}, + {m68k_op_sub_32_re_di , 0xf1f8, 0x91a8, 24}, + {m68k_op_sub_32_re_ix , 0xf1f8, 0x91b0, 26}, + {m68k_op_suba_32_d , 0xf1f8, 0x91c0, 8}, + {m68k_op_suba_32_a , 0xf1f8, 0x91c8, 8}, + {m68k_op_suba_32_ai , 0xf1f8, 0x91d0, 14}, + {m68k_op_suba_32_pi , 0xf1f8, 0x91d8, 14}, + {m68k_op_suba_32_pd , 0xf1f8, 0x91e0, 16}, + {m68k_op_suba_32_di , 0xf1f8, 0x91e8, 18}, + {m68k_op_suba_32_ix , 0xf1f8, 0x91f0, 20}, + {m68k_op_cmp_8_d , 0xf1f8, 0xb000, 4}, + {m68k_op_cmp_8_ai , 0xf1f8, 0xb010, 8}, + {m68k_op_cmp_8_pi , 0xf1f8, 0xb018, 8}, + {m68k_op_cmp_8_pd , 0xf1f8, 0xb020, 10}, + {m68k_op_cmp_8_di , 0xf1f8, 0xb028, 12}, + {m68k_op_cmp_8_ix , 0xf1f8, 0xb030, 14}, + {m68k_op_cmp_16_d , 0xf1f8, 0xb040, 4}, + {m68k_op_cmp_16_a , 0xf1f8, 0xb048, 4}, + {m68k_op_cmp_16_ai , 0xf1f8, 0xb050, 8}, + {m68k_op_cmp_16_pi , 0xf1f8, 0xb058, 8}, + {m68k_op_cmp_16_pd , 0xf1f8, 0xb060, 10}, + {m68k_op_cmp_16_di , 0xf1f8, 0xb068, 12}, + {m68k_op_cmp_16_ix , 0xf1f8, 0xb070, 14}, + {m68k_op_cmp_32_d , 0xf1f8, 0xb080, 6}, + {m68k_op_cmp_32_a , 0xf1f8, 0xb088, 6}, + {m68k_op_cmp_32_ai , 0xf1f8, 0xb090, 14}, + {m68k_op_cmp_32_pi , 0xf1f8, 0xb098, 14}, + {m68k_op_cmp_32_pd , 0xf1f8, 0xb0a0, 16}, + {m68k_op_cmp_32_di , 0xf1f8, 0xb0a8, 18}, + {m68k_op_cmp_32_ix , 0xf1f8, 0xb0b0, 20}, + {m68k_op_cmpa_16_d , 0xf1f8, 0xb0c0, 6}, + {m68k_op_cmpa_16_a , 0xf1f8, 0xb0c8, 6}, + {m68k_op_cmpa_16_ai , 0xf1f8, 0xb0d0, 10}, + {m68k_op_cmpa_16_pi , 0xf1f8, 0xb0d8, 10}, + {m68k_op_cmpa_16_pd , 0xf1f8, 0xb0e0, 12}, + {m68k_op_cmpa_16_di , 0xf1f8, 0xb0e8, 14}, + {m68k_op_cmpa_16_ix , 0xf1f8, 0xb0f0, 16}, + {m68k_op_eor_8_d , 0xf1f8, 0xb100, 4}, + {m68k_op_cmpm_8 , 0xf1f8, 0xb108, 12}, + {m68k_op_eor_8_ai , 0xf1f8, 0xb110, 12}, + {m68k_op_eor_8_pi , 0xf1f8, 0xb118, 12}, + {m68k_op_eor_8_pd , 0xf1f8, 0xb120, 14}, + {m68k_op_eor_8_di , 0xf1f8, 0xb128, 16}, + {m68k_op_eor_8_ix , 0xf1f8, 0xb130, 18}, + {m68k_op_eor_16_d , 0xf1f8, 0xb140, 4}, + {m68k_op_cmpm_16 , 0xf1f8, 0xb148, 12}, + {m68k_op_eor_16_ai , 0xf1f8, 0xb150, 12}, + {m68k_op_eor_16_pi , 0xf1f8, 0xb158, 12}, + {m68k_op_eor_16_pd , 0xf1f8, 0xb160, 14}, + {m68k_op_eor_16_di , 0xf1f8, 0xb168, 16}, + {m68k_op_eor_16_ix , 0xf1f8, 0xb170, 18}, + {m68k_op_eor_32_d , 0xf1f8, 0xb180, 8}, + {m68k_op_cmpm_32 , 0xf1f8, 0xb188, 20}, + {m68k_op_eor_32_ai , 0xf1f8, 0xb190, 20}, + {m68k_op_eor_32_pi , 0xf1f8, 0xb198, 20}, + {m68k_op_eor_32_pd , 0xf1f8, 0xb1a0, 22}, + {m68k_op_eor_32_di , 0xf1f8, 0xb1a8, 24}, + {m68k_op_eor_32_ix , 0xf1f8, 0xb1b0, 26}, + {m68k_op_cmpa_32_d , 0xf1f8, 0xb1c0, 6}, + {m68k_op_cmpa_32_a , 0xf1f8, 0xb1c8, 6}, + {m68k_op_cmpa_32_ai , 0xf1f8, 0xb1d0, 14}, + {m68k_op_cmpa_32_pi , 0xf1f8, 0xb1d8, 14}, + {m68k_op_cmpa_32_pd , 0xf1f8, 0xb1e0, 16}, + {m68k_op_cmpa_32_di , 0xf1f8, 0xb1e8, 18}, + {m68k_op_cmpa_32_ix , 0xf1f8, 0xb1f0, 20}, + {m68k_op_and_8_er_d , 0xf1f8, 0xc000, 4}, + {m68k_op_and_8_er_ai , 0xf1f8, 0xc010, 8}, + {m68k_op_and_8_er_pi , 0xf1f8, 0xc018, 8}, + {m68k_op_and_8_er_pd , 0xf1f8, 0xc020, 10}, + {m68k_op_and_8_er_di , 0xf1f8, 0xc028, 12}, + {m68k_op_and_8_er_ix , 0xf1f8, 0xc030, 14}, + {m68k_op_and_16_er_d , 0xf1f8, 0xc040, 4}, + {m68k_op_and_16_er_ai , 0xf1f8, 0xc050, 8}, + {m68k_op_and_16_er_pi , 0xf1f8, 0xc058, 8}, + {m68k_op_and_16_er_pd , 0xf1f8, 0xc060, 10}, + {m68k_op_and_16_er_di , 0xf1f8, 0xc068, 12}, + {m68k_op_and_16_er_ix , 0xf1f8, 0xc070, 14}, + {m68k_op_and_32_er_d , 0xf1f8, 0xc080, 8}, + {m68k_op_and_32_er_ai , 0xf1f8, 0xc090, 14}, + {m68k_op_and_32_er_pi , 0xf1f8, 0xc098, 14}, + {m68k_op_and_32_er_pd , 0xf1f8, 0xc0a0, 16}, + {m68k_op_and_32_er_di , 0xf1f8, 0xc0a8, 18}, + {m68k_op_and_32_er_ix , 0xf1f8, 0xc0b0, 20}, + {m68k_op_mulu_16_d , 0xf1f8, 0xc0c0, 0}, + {m68k_op_mulu_16_ai , 0xf1f8, 0xc0d0, 4}, + {m68k_op_mulu_16_pi , 0xf1f8, 0xc0d8, 4}, + {m68k_op_mulu_16_pd , 0xf1f8, 0xc0e0, 6}, + {m68k_op_mulu_16_di , 0xf1f8, 0xc0e8, 8}, + {m68k_op_mulu_16_ix , 0xf1f8, 0xc0f0, 10}, + {m68k_op_abcd_8_rr , 0xf1f8, 0xc100, 6}, + {m68k_op_abcd_8_mm , 0xf1f8, 0xc108, 18}, + {m68k_op_and_8_re_ai , 0xf1f8, 0xc110, 12}, + {m68k_op_and_8_re_pi , 0xf1f8, 0xc118, 12}, + {m68k_op_and_8_re_pd , 0xf1f8, 0xc120, 14}, + {m68k_op_and_8_re_di , 0xf1f8, 0xc128, 16}, + {m68k_op_and_8_re_ix , 0xf1f8, 0xc130, 18}, + {m68k_op_exg_32_dd , 0xf1f8, 0xc140, 6}, + {m68k_op_exg_32_aa , 0xf1f8, 0xc148, 6}, + {m68k_op_and_16_re_ai , 0xf1f8, 0xc150, 12}, + {m68k_op_and_16_re_pi , 0xf1f8, 0xc158, 12}, + {m68k_op_and_16_re_pd , 0xf1f8, 0xc160, 14}, + {m68k_op_and_16_re_di , 0xf1f8, 0xc168, 16}, + {m68k_op_and_16_re_ix , 0xf1f8, 0xc170, 18}, + {m68k_op_exg_32_da , 0xf1f8, 0xc188, 6}, + {m68k_op_and_32_re_ai , 0xf1f8, 0xc190, 20}, + {m68k_op_and_32_re_pi , 0xf1f8, 0xc198, 20}, + {m68k_op_and_32_re_pd , 0xf1f8, 0xc1a0, 22}, + {m68k_op_and_32_re_di , 0xf1f8, 0xc1a8, 24}, + {m68k_op_and_32_re_ix , 0xf1f8, 0xc1b0, 26}, + {m68k_op_muls_16_d , 0xf1f8, 0xc1c0, 0}, + {m68k_op_muls_16_ai , 0xf1f8, 0xc1d0, 4}, + {m68k_op_muls_16_pi , 0xf1f8, 0xc1d8, 4}, + {m68k_op_muls_16_pd , 0xf1f8, 0xc1e0, 6}, + {m68k_op_muls_16_di , 0xf1f8, 0xc1e8, 8}, + {m68k_op_muls_16_ix , 0xf1f8, 0xc1f0, 10}, + {m68k_op_add_8_er_d , 0xf1f8, 0xd000, 4}, + {m68k_op_add_8_er_ai , 0xf1f8, 0xd010, 8}, + {m68k_op_add_8_er_pi , 0xf1f8, 0xd018, 8}, + {m68k_op_add_8_er_pd , 0xf1f8, 0xd020, 10}, + {m68k_op_add_8_er_di , 0xf1f8, 0xd028, 12}, + {m68k_op_add_8_er_ix , 0xf1f8, 0xd030, 14}, + {m68k_op_add_16_er_d , 0xf1f8, 0xd040, 4}, + {m68k_op_add_16_er_a , 0xf1f8, 0xd048, 4}, + {m68k_op_add_16_er_ai , 0xf1f8, 0xd050, 8}, + {m68k_op_add_16_er_pi , 0xf1f8, 0xd058, 8}, + {m68k_op_add_16_er_pd , 0xf1f8, 0xd060, 10}, + {m68k_op_add_16_er_di , 0xf1f8, 0xd068, 12}, + {m68k_op_add_16_er_ix , 0xf1f8, 0xd070, 14}, + {m68k_op_add_32_er_d , 0xf1f8, 0xd080, 8}, + {m68k_op_add_32_er_a , 0xf1f8, 0xd088, 8}, + {m68k_op_add_32_er_ai , 0xf1f8, 0xd090, 14}, + {m68k_op_add_32_er_pi , 0xf1f8, 0xd098, 14}, + {m68k_op_add_32_er_pd , 0xf1f8, 0xd0a0, 16}, + {m68k_op_add_32_er_di , 0xf1f8, 0xd0a8, 18}, + {m68k_op_add_32_er_ix , 0xf1f8, 0xd0b0, 20}, + {m68k_op_adda_16_d , 0xf1f8, 0xd0c0, 8}, + {m68k_op_adda_16_a , 0xf1f8, 0xd0c8, 8}, + {m68k_op_adda_16_ai , 0xf1f8, 0xd0d0, 12}, + {m68k_op_adda_16_pi , 0xf1f8, 0xd0d8, 12}, + {m68k_op_adda_16_pd , 0xf1f8, 0xd0e0, 14}, + {m68k_op_adda_16_di , 0xf1f8, 0xd0e8, 16}, + {m68k_op_adda_16_ix , 0xf1f8, 0xd0f0, 18}, + {m68k_op_addx_8_rr , 0xf1f8, 0xd100, 4}, + {m68k_op_addx_8_mm , 0xf1f8, 0xd108, 18}, + {m68k_op_add_8_re_ai , 0xf1f8, 0xd110, 12}, + {m68k_op_add_8_re_pi , 0xf1f8, 0xd118, 12}, + {m68k_op_add_8_re_pd , 0xf1f8, 0xd120, 14}, + {m68k_op_add_8_re_di , 0xf1f8, 0xd128, 16}, + {m68k_op_add_8_re_ix , 0xf1f8, 0xd130, 18}, + {m68k_op_addx_16_rr , 0xf1f8, 0xd140, 4}, + {m68k_op_addx_16_mm , 0xf1f8, 0xd148, 18}, + {m68k_op_add_16_re_ai , 0xf1f8, 0xd150, 12}, + {m68k_op_add_16_re_pi , 0xf1f8, 0xd158, 12}, + {m68k_op_add_16_re_pd , 0xf1f8, 0xd160, 14}, + {m68k_op_add_16_re_di , 0xf1f8, 0xd168, 16}, + {m68k_op_add_16_re_ix , 0xf1f8, 0xd170, 18}, + {m68k_op_addx_32_rr , 0xf1f8, 0xd180, 8}, + {m68k_op_addx_32_mm , 0xf1f8, 0xd188, 30}, + {m68k_op_add_32_re_ai , 0xf1f8, 0xd190, 20}, + {m68k_op_add_32_re_pi , 0xf1f8, 0xd198, 20}, + {m68k_op_add_32_re_pd , 0xf1f8, 0xd1a0, 22}, + {m68k_op_add_32_re_di , 0xf1f8, 0xd1a8, 24}, + {m68k_op_add_32_re_ix , 0xf1f8, 0xd1b0, 26}, + {m68k_op_adda_32_d , 0xf1f8, 0xd1c0, 8}, + {m68k_op_adda_32_a , 0xf1f8, 0xd1c8, 8}, + {m68k_op_adda_32_ai , 0xf1f8, 0xd1d0, 14}, + {m68k_op_adda_32_pi , 0xf1f8, 0xd1d8, 14}, + {m68k_op_adda_32_pd , 0xf1f8, 0xd1e0, 16}, + {m68k_op_adda_32_di , 0xf1f8, 0xd1e8, 18}, + {m68k_op_adda_32_ix , 0xf1f8, 0xd1f0, 20}, + {m68k_op_asr_8_s , 0xf1f8, 0xe000, 6}, + {m68k_op_lsr_8_s , 0xf1f8, 0xe008, 6}, + {m68k_op_roxr_8_s , 0xf1f8, 0xe010, 6}, + {m68k_op_ror_8_s , 0xf1f8, 0xe018, 6}, + {m68k_op_asr_8_r , 0xf1f8, 0xe020, 6}, + {m68k_op_lsr_8_r , 0xf1f8, 0xe028, 6}, + {m68k_op_roxr_8_r , 0xf1f8, 0xe030, 6}, + {m68k_op_ror_8_r , 0xf1f8, 0xe038, 6}, + {m68k_op_asr_16_s , 0xf1f8, 0xe040, 6}, + {m68k_op_lsr_16_s , 0xf1f8, 0xe048, 6}, + {m68k_op_roxr_16_s , 0xf1f8, 0xe050, 6}, + {m68k_op_ror_16_s , 0xf1f8, 0xe058, 6}, + {m68k_op_asr_16_r , 0xf1f8, 0xe060, 6}, + {m68k_op_lsr_16_r , 0xf1f8, 0xe068, 6}, + {m68k_op_roxr_16_r , 0xf1f8, 0xe070, 6}, + {m68k_op_ror_16_r , 0xf1f8, 0xe078, 6}, + {m68k_op_asr_32_s , 0xf1f8, 0xe080, 8}, + {m68k_op_lsr_32_s , 0xf1f8, 0xe088, 8}, + {m68k_op_roxr_32_s , 0xf1f8, 0xe090, 8}, + {m68k_op_ror_32_s , 0xf1f8, 0xe098, 8}, + {m68k_op_asr_32_r , 0xf1f8, 0xe0a0, 8}, + {m68k_op_lsr_32_r , 0xf1f8, 0xe0a8, 8}, + {m68k_op_roxr_32_r , 0xf1f8, 0xe0b0, 8}, + {m68k_op_ror_32_r , 0xf1f8, 0xe0b8, 8}, + {m68k_op_asl_8_s , 0xf1f8, 0xe100, 6}, + {m68k_op_lsl_8_s , 0xf1f8, 0xe108, 6}, + {m68k_op_roxl_8_s , 0xf1f8, 0xe110, 6}, + {m68k_op_rol_8_s , 0xf1f8, 0xe118, 6}, + {m68k_op_asl_8_r , 0xf1f8, 0xe120, 6}, + {m68k_op_lsl_8_r , 0xf1f8, 0xe128, 6}, + {m68k_op_roxl_8_r , 0xf1f8, 0xe130, 6}, + {m68k_op_rol_8_r , 0xf1f8, 0xe138, 6}, + {m68k_op_asl_16_s , 0xf1f8, 0xe140, 6}, + {m68k_op_lsl_16_s , 0xf1f8, 0xe148, 6}, + {m68k_op_roxl_16_s , 0xf1f8, 0xe150, 6}, + {m68k_op_rol_16_s , 0xf1f8, 0xe158, 6}, + {m68k_op_asl_16_r , 0xf1f8, 0xe160, 6}, + {m68k_op_lsl_16_r , 0xf1f8, 0xe168, 6}, + {m68k_op_roxl_16_r , 0xf1f8, 0xe170, 6}, + {m68k_op_rol_16_r , 0xf1f8, 0xe178, 6}, + {m68k_op_asl_32_s , 0xf1f8, 0xe180, 8}, + {m68k_op_lsl_32_s , 0xf1f8, 0xe188, 8}, + {m68k_op_roxl_32_s , 0xf1f8, 0xe190, 8}, + {m68k_op_rol_32_s , 0xf1f8, 0xe198, 8}, + {m68k_op_asl_32_r , 0xf1f8, 0xe1a0, 8}, + {m68k_op_lsl_32_r , 0xf1f8, 0xe1a8, 8}, + {m68k_op_roxl_32_r , 0xf1f8, 0xe1b0, 8}, + {m68k_op_rol_32_r , 0xf1f8, 0xe1b8, 8}, + {m68k_op_trap , 0xfff0, 0x4e40, 4}, + {m68k_op_btst_8_r_pi7 , 0xf1ff, 0x011f, 8}, + {m68k_op_btst_8_r_pd7 , 0xf1ff, 0x0127, 10}, + {m68k_op_btst_8_r_aw , 0xf1ff, 0x0138, 12}, + {m68k_op_btst_8_r_al , 0xf1ff, 0x0139, 16}, + {m68k_op_btst_8_r_pcdi , 0xf1ff, 0x013a, 12}, + {m68k_op_btst_8_r_pcix , 0xf1ff, 0x013b, 14}, + {m68k_op_btst_8_r_i , 0xf1ff, 0x013c, 8}, + {m68k_op_bchg_8_r_pi7 , 0xf1ff, 0x015f, 12}, + {m68k_op_bchg_8_r_pd7 , 0xf1ff, 0x0167, 14}, + {m68k_op_bchg_8_r_aw , 0xf1ff, 0x0178, 16}, + {m68k_op_bchg_8_r_al , 0xf1ff, 0x0179, 20}, + {m68k_op_bclr_8_r_pi7 , 0xf1ff, 0x019f, 12}, + {m68k_op_bclr_8_r_pd7 , 0xf1ff, 0x01a7, 14}, + {m68k_op_bclr_8_r_aw , 0xf1ff, 0x01b8, 16}, + {m68k_op_bclr_8_r_al , 0xf1ff, 0x01b9, 20}, + {m68k_op_bset_8_r_pi7 , 0xf1ff, 0x01df, 12}, + {m68k_op_bset_8_r_pd7 , 0xf1ff, 0x01e7, 14}, + {m68k_op_bset_8_r_aw , 0xf1ff, 0x01f8, 16}, + {m68k_op_bset_8_r_al , 0xf1ff, 0x01f9, 20}, + {m68k_op_move_8_d_pi7 , 0xf1ff, 0x101f, 8}, + {m68k_op_move_8_d_pd7 , 0xf1ff, 0x1027, 10}, + {m68k_op_move_8_d_aw , 0xf1ff, 0x1038, 12}, + {m68k_op_move_8_d_al , 0xf1ff, 0x1039, 16}, + {m68k_op_move_8_d_pcdi , 0xf1ff, 0x103a, 12}, + {m68k_op_move_8_d_pcix , 0xf1ff, 0x103b, 14}, + {m68k_op_move_8_d_i , 0xf1ff, 0x103c, 8}, + {m68k_op_move_8_ai_pi7 , 0xf1ff, 0x109f, 12}, + {m68k_op_move_8_ai_pd7 , 0xf1ff, 0x10a7, 14}, + {m68k_op_move_8_ai_aw , 0xf1ff, 0x10b8, 16}, + {m68k_op_move_8_ai_al , 0xf1ff, 0x10b9, 20}, + {m68k_op_move_8_ai_pcdi , 0xf1ff, 0x10ba, 16}, + {m68k_op_move_8_ai_pcix , 0xf1ff, 0x10bb, 18}, + {m68k_op_move_8_ai_i , 0xf1ff, 0x10bc, 12}, + {m68k_op_move_8_pi_pi7 , 0xf1ff, 0x10df, 12}, + {m68k_op_move_8_pi_pd7 , 0xf1ff, 0x10e7, 14}, + {m68k_op_move_8_pi_aw , 0xf1ff, 0x10f8, 16}, + {m68k_op_move_8_pi_al , 0xf1ff, 0x10f9, 20}, + {m68k_op_move_8_pi_pcdi , 0xf1ff, 0x10fa, 16}, + {m68k_op_move_8_pi_pcix , 0xf1ff, 0x10fb, 18}, + {m68k_op_move_8_pi_i , 0xf1ff, 0x10fc, 12}, + {m68k_op_move_8_pd_pi7 , 0xf1ff, 0x111f, 12}, + {m68k_op_move_8_pd_pd7 , 0xf1ff, 0x1127, 14}, + {m68k_op_move_8_pd_aw , 0xf1ff, 0x1138, 16}, + {m68k_op_move_8_pd_al , 0xf1ff, 0x1139, 20}, + {m68k_op_move_8_pd_pcdi , 0xf1ff, 0x113a, 16}, + {m68k_op_move_8_pd_pcix , 0xf1ff, 0x113b, 18}, + {m68k_op_move_8_pd_i , 0xf1ff, 0x113c, 12}, + {m68k_op_move_8_di_pi7 , 0xf1ff, 0x115f, 16}, + {m68k_op_move_8_di_pd7 , 0xf1ff, 0x1167, 18}, + {m68k_op_move_8_di_aw , 0xf1ff, 0x1178, 20}, + {m68k_op_move_8_di_al , 0xf1ff, 0x1179, 24}, + {m68k_op_move_8_di_pcdi , 0xf1ff, 0x117a, 20}, + {m68k_op_move_8_di_pcix , 0xf1ff, 0x117b, 22}, + {m68k_op_move_8_di_i , 0xf1ff, 0x117c, 16}, + {m68k_op_move_8_ix_pi7 , 0xf1ff, 0x119f, 18}, + {m68k_op_move_8_ix_pd7 , 0xf1ff, 0x11a7, 20}, + {m68k_op_move_8_ix_aw , 0xf1ff, 0x11b8, 22}, + {m68k_op_move_8_ix_al , 0xf1ff, 0x11b9, 26}, + {m68k_op_move_8_ix_pcdi , 0xf1ff, 0x11ba, 22}, + {m68k_op_move_8_ix_pcix , 0xf1ff, 0x11bb, 24}, + {m68k_op_move_8_ix_i , 0xf1ff, 0x11bc, 18}, + {m68k_op_move_32_d_aw , 0xf1ff, 0x2038, 16}, + {m68k_op_move_32_d_al , 0xf1ff, 0x2039, 20}, + {m68k_op_move_32_d_pcdi , 0xf1ff, 0x203a, 16}, + {m68k_op_move_32_d_pcix , 0xf1ff, 0x203b, 18}, + {m68k_op_move_32_d_i , 0xf1ff, 0x203c, 12}, + {m68k_op_movea_32_aw , 0xf1ff, 0x2078, 16}, + {m68k_op_movea_32_al , 0xf1ff, 0x2079, 20}, + {m68k_op_movea_32_pcdi , 0xf1ff, 0x207a, 16}, + {m68k_op_movea_32_pcix , 0xf1ff, 0x207b, 18}, + {m68k_op_movea_32_i , 0xf1ff, 0x207c, 12}, + {m68k_op_move_32_ai_aw , 0xf1ff, 0x20b8, 24}, + {m68k_op_move_32_ai_al , 0xf1ff, 0x20b9, 28}, + {m68k_op_move_32_ai_pcdi , 0xf1ff, 0x20ba, 24}, + {m68k_op_move_32_ai_pcix , 0xf1ff, 0x20bb, 26}, + {m68k_op_move_32_ai_i , 0xf1ff, 0x20bc, 20}, + {m68k_op_move_32_pi_aw , 0xf1ff, 0x20f8, 24}, + {m68k_op_move_32_pi_al , 0xf1ff, 0x20f9, 28}, + {m68k_op_move_32_pi_pcdi , 0xf1ff, 0x20fa, 24}, + {m68k_op_move_32_pi_pcix , 0xf1ff, 0x20fb, 26}, + {m68k_op_move_32_pi_i , 0xf1ff, 0x20fc, 20}, + {m68k_op_move_32_pd_aw , 0xf1ff, 0x2138, 24}, + {m68k_op_move_32_pd_al , 0xf1ff, 0x2139, 28}, + {m68k_op_move_32_pd_pcdi , 0xf1ff, 0x213a, 24}, + {m68k_op_move_32_pd_pcix , 0xf1ff, 0x213b, 26}, + {m68k_op_move_32_pd_i , 0xf1ff, 0x213c, 20}, + {m68k_op_move_32_di_aw , 0xf1ff, 0x2178, 28}, + {m68k_op_move_32_di_al , 0xf1ff, 0x2179, 32}, + {m68k_op_move_32_di_pcdi , 0xf1ff, 0x217a, 28}, + {m68k_op_move_32_di_pcix , 0xf1ff, 0x217b, 30}, + {m68k_op_move_32_di_i , 0xf1ff, 0x217c, 24}, + {m68k_op_move_32_ix_aw , 0xf1ff, 0x21b8, 30}, + {m68k_op_move_32_ix_al , 0xf1ff, 0x21b9, 34}, + {m68k_op_move_32_ix_pcdi , 0xf1ff, 0x21ba, 30}, + {m68k_op_move_32_ix_pcix , 0xf1ff, 0x21bb, 32}, + {m68k_op_move_32_ix_i , 0xf1ff, 0x21bc, 26}, + {m68k_op_move_16_d_aw , 0xf1ff, 0x3038, 12}, + {m68k_op_move_16_d_al , 0xf1ff, 0x3039, 16}, + {m68k_op_move_16_d_pcdi , 0xf1ff, 0x303a, 12}, + {m68k_op_move_16_d_pcix , 0xf1ff, 0x303b, 14}, + {m68k_op_move_16_d_i , 0xf1ff, 0x303c, 8}, + {m68k_op_movea_16_aw , 0xf1ff, 0x3078, 12}, + {m68k_op_movea_16_al , 0xf1ff, 0x3079, 16}, + {m68k_op_movea_16_pcdi , 0xf1ff, 0x307a, 12}, + {m68k_op_movea_16_pcix , 0xf1ff, 0x307b, 14}, + {m68k_op_movea_16_i , 0xf1ff, 0x307c, 8}, + {m68k_op_move_16_ai_aw , 0xf1ff, 0x30b8, 16}, + {m68k_op_move_16_ai_al , 0xf1ff, 0x30b9, 20}, + {m68k_op_move_16_ai_pcdi , 0xf1ff, 0x30ba, 16}, + {m68k_op_move_16_ai_pcix , 0xf1ff, 0x30bb, 18}, + {m68k_op_move_16_ai_i , 0xf1ff, 0x30bc, 12}, + {m68k_op_move_16_pi_aw , 0xf1ff, 0x30f8, 16}, + {m68k_op_move_16_pi_al , 0xf1ff, 0x30f9, 20}, + {m68k_op_move_16_pi_pcdi , 0xf1ff, 0x30fa, 16}, + {m68k_op_move_16_pi_pcix , 0xf1ff, 0x30fb, 18}, + {m68k_op_move_16_pi_i , 0xf1ff, 0x30fc, 12}, + {m68k_op_move_16_pd_aw , 0xf1ff, 0x3138, 16}, + {m68k_op_move_16_pd_al , 0xf1ff, 0x3139, 20}, + {m68k_op_move_16_pd_pcdi , 0xf1ff, 0x313a, 16}, + {m68k_op_move_16_pd_pcix , 0xf1ff, 0x313b, 18}, + {m68k_op_move_16_pd_i , 0xf1ff, 0x313c, 12}, + {m68k_op_move_16_di_aw , 0xf1ff, 0x3178, 20}, + {m68k_op_move_16_di_al , 0xf1ff, 0x3179, 24}, + {m68k_op_move_16_di_pcdi , 0xf1ff, 0x317a, 20}, + {m68k_op_move_16_di_pcix , 0xf1ff, 0x317b, 22}, + {m68k_op_move_16_di_i , 0xf1ff, 0x317c, 16}, + {m68k_op_move_16_ix_aw , 0xf1ff, 0x31b8, 22}, + {m68k_op_move_16_ix_al , 0xf1ff, 0x31b9, 26}, + {m68k_op_move_16_ix_pcdi , 0xf1ff, 0x31ba, 22}, + {m68k_op_move_16_ix_pcix , 0xf1ff, 0x31bb, 24}, + {m68k_op_move_16_ix_i , 0xf1ff, 0x31bc, 18}, + {m68k_op_chk_16_aw , 0xf1ff, 0x41b8, 18}, + {m68k_op_chk_16_al , 0xf1ff, 0x41b9, 22}, + {m68k_op_chk_16_pcdi , 0xf1ff, 0x41ba, 18}, + {m68k_op_chk_16_pcix , 0xf1ff, 0x41bb, 20}, + {m68k_op_chk_16_i , 0xf1ff, 0x41bc, 14}, + {m68k_op_lea_32_aw , 0xf1ff, 0x41f8, 8}, + {m68k_op_lea_32_al , 0xf1ff, 0x41f9, 12}, + {m68k_op_lea_32_pcdi , 0xf1ff, 0x41fa, 8}, + {m68k_op_lea_32_pcix , 0xf1ff, 0x41fb, 12}, + {m68k_op_addq_8_pi7 , 0xf1ff, 0x501f, 12}, + {m68k_op_addq_8_pd7 , 0xf1ff, 0x5027, 14}, + {m68k_op_addq_8_aw , 0xf1ff, 0x5038, 16}, + {m68k_op_addq_8_al , 0xf1ff, 0x5039, 20}, + {m68k_op_addq_16_aw , 0xf1ff, 0x5078, 16}, + {m68k_op_addq_16_al , 0xf1ff, 0x5079, 20}, + {m68k_op_addq_32_aw , 0xf1ff, 0x50b8, 24}, + {m68k_op_addq_32_al , 0xf1ff, 0x50b9, 28}, + {m68k_op_subq_8_pi7 , 0xf1ff, 0x511f, 12}, + {m68k_op_subq_8_pd7 , 0xf1ff, 0x5127, 14}, + {m68k_op_subq_8_aw , 0xf1ff, 0x5138, 16}, + {m68k_op_subq_8_al , 0xf1ff, 0x5139, 20}, + {m68k_op_subq_16_aw , 0xf1ff, 0x5178, 16}, + {m68k_op_subq_16_al , 0xf1ff, 0x5179, 20}, + {m68k_op_subq_32_aw , 0xf1ff, 0x51b8, 24}, + {m68k_op_subq_32_al , 0xf1ff, 0x51b9, 28}, + {m68k_op_or_8_er_pi7 , 0xf1ff, 0x801f, 8}, + {m68k_op_or_8_er_pd7 , 0xf1ff, 0x8027, 10}, + {m68k_op_or_8_er_aw , 0xf1ff, 0x8038, 12}, + {m68k_op_or_8_er_al , 0xf1ff, 0x8039, 16}, + {m68k_op_or_8_er_pcdi , 0xf1ff, 0x803a, 12}, + {m68k_op_or_8_er_pcix , 0xf1ff, 0x803b, 14}, + {m68k_op_or_8_er_i , 0xf1ff, 0x803c, 8}, + {m68k_op_or_16_er_aw , 0xf1ff, 0x8078, 12}, + {m68k_op_or_16_er_al , 0xf1ff, 0x8079, 16}, + {m68k_op_or_16_er_pcdi , 0xf1ff, 0x807a, 12}, + {m68k_op_or_16_er_pcix , 0xf1ff, 0x807b, 14}, + {m68k_op_or_16_er_i , 0xf1ff, 0x807c, 8}, + {m68k_op_or_32_er_aw , 0xf1ff, 0x80b8, 18}, + {m68k_op_or_32_er_al , 0xf1ff, 0x80b9, 22}, + {m68k_op_or_32_er_pcdi , 0xf1ff, 0x80ba, 18}, + {m68k_op_or_32_er_pcix , 0xf1ff, 0x80bb, 20}, + {m68k_op_or_32_er_i , 0xf1ff, 0x80bc, 16}, + {m68k_op_divu_16_aw , 0xf1ff, 0x80f8, 8}, + {m68k_op_divu_16_al , 0xf1ff, 0x80f9, 12}, + {m68k_op_divu_16_pcdi , 0xf1ff, 0x80fa, 8}, + {m68k_op_divu_16_pcix , 0xf1ff, 0x80fb, 10}, + {m68k_op_divu_16_i , 0xf1ff, 0x80fc, 4}, + {m68k_op_sbcd_8_mm_ay7 , 0xf1ff, 0x810f, 18}, + {m68k_op_or_8_re_pi7 , 0xf1ff, 0x811f, 12}, + {m68k_op_or_8_re_pd7 , 0xf1ff, 0x8127, 14}, + {m68k_op_or_8_re_aw , 0xf1ff, 0x8138, 16}, + {m68k_op_or_8_re_al , 0xf1ff, 0x8139, 20}, + {m68k_op_or_16_re_aw , 0xf1ff, 0x8178, 16}, + {m68k_op_or_16_re_al , 0xf1ff, 0x8179, 20}, + {m68k_op_or_32_re_aw , 0xf1ff, 0x81b8, 24}, + {m68k_op_or_32_re_al , 0xf1ff, 0x81b9, 28}, + {m68k_op_divs_16_aw , 0xf1ff, 0x81f8, 8}, + {m68k_op_divs_16_al , 0xf1ff, 0x81f9, 12}, + {m68k_op_divs_16_pcdi , 0xf1ff, 0x81fa, 8}, + {m68k_op_divs_16_pcix , 0xf1ff, 0x81fb, 10}, + {m68k_op_divs_16_i , 0xf1ff, 0x81fc, 4}, + {m68k_op_sub_8_er_pi7 , 0xf1ff, 0x901f, 8}, + {m68k_op_sub_8_er_pd7 , 0xf1ff, 0x9027, 10}, + {m68k_op_sub_8_er_aw , 0xf1ff, 0x9038, 12}, + {m68k_op_sub_8_er_al , 0xf1ff, 0x9039, 16}, + {m68k_op_sub_8_er_pcdi , 0xf1ff, 0x903a, 12}, + {m68k_op_sub_8_er_pcix , 0xf1ff, 0x903b, 14}, + {m68k_op_sub_8_er_i , 0xf1ff, 0x903c, 8}, + {m68k_op_sub_16_er_aw , 0xf1ff, 0x9078, 12}, + {m68k_op_sub_16_er_al , 0xf1ff, 0x9079, 16}, + {m68k_op_sub_16_er_pcdi , 0xf1ff, 0x907a, 12}, + {m68k_op_sub_16_er_pcix , 0xf1ff, 0x907b, 14}, + {m68k_op_sub_16_er_i , 0xf1ff, 0x907c, 8}, + {m68k_op_sub_32_er_aw , 0xf1ff, 0x90b8, 18}, + {m68k_op_sub_32_er_al , 0xf1ff, 0x90b9, 22}, + {m68k_op_sub_32_er_pcdi , 0xf1ff, 0x90ba, 18}, + {m68k_op_sub_32_er_pcix , 0xf1ff, 0x90bb, 20}, + {m68k_op_sub_32_er_i , 0xf1ff, 0x90bc, 16}, + {m68k_op_suba_16_aw , 0xf1ff, 0x90f8, 16}, + {m68k_op_suba_16_al , 0xf1ff, 0x90f9, 20}, + {m68k_op_suba_16_pcdi , 0xf1ff, 0x90fa, 16}, + {m68k_op_suba_16_pcix , 0xf1ff, 0x90fb, 18}, + {m68k_op_suba_16_i , 0xf1ff, 0x90fc, 12}, + {m68k_op_subx_8_mm_ay7 , 0xf1ff, 0x910f, 18}, + {m68k_op_sub_8_re_pi7 , 0xf1ff, 0x911f, 12}, + {m68k_op_sub_8_re_pd7 , 0xf1ff, 0x9127, 14}, + {m68k_op_sub_8_re_aw , 0xf1ff, 0x9138, 16}, + {m68k_op_sub_8_re_al , 0xf1ff, 0x9139, 20}, + {m68k_op_sub_16_re_aw , 0xf1ff, 0x9178, 16}, + {m68k_op_sub_16_re_al , 0xf1ff, 0x9179, 20}, + {m68k_op_sub_32_re_aw , 0xf1ff, 0x91b8, 24}, + {m68k_op_sub_32_re_al , 0xf1ff, 0x91b9, 28}, + {m68k_op_suba_32_aw , 0xf1ff, 0x91f8, 18}, + {m68k_op_suba_32_al , 0xf1ff, 0x91f9, 22}, + {m68k_op_suba_32_pcdi , 0xf1ff, 0x91fa, 18}, + {m68k_op_suba_32_pcix , 0xf1ff, 0x91fb, 20}, + {m68k_op_suba_32_i , 0xf1ff, 0x91fc, 16}, + {m68k_op_cmp_8_pi7 , 0xf1ff, 0xb01f, 8}, + {m68k_op_cmp_8_pd7 , 0xf1ff, 0xb027, 10}, + {m68k_op_cmp_8_aw , 0xf1ff, 0xb038, 12}, + {m68k_op_cmp_8_al , 0xf1ff, 0xb039, 16}, + {m68k_op_cmp_8_pcdi , 0xf1ff, 0xb03a, 12}, + {m68k_op_cmp_8_pcix , 0xf1ff, 0xb03b, 14}, + {m68k_op_cmp_8_i , 0xf1ff, 0xb03c, 8}, + {m68k_op_cmp_16_aw , 0xf1ff, 0xb078, 12}, + {m68k_op_cmp_16_al , 0xf1ff, 0xb079, 16}, + {m68k_op_cmp_16_pcdi , 0xf1ff, 0xb07a, 12}, + {m68k_op_cmp_16_pcix , 0xf1ff, 0xb07b, 14}, + {m68k_op_cmp_16_i , 0xf1ff, 0xb07c, 8}, + {m68k_op_cmp_32_aw , 0xf1ff, 0xb0b8, 18}, + {m68k_op_cmp_32_al , 0xf1ff, 0xb0b9, 22}, + {m68k_op_cmp_32_pcdi , 0xf1ff, 0xb0ba, 18}, + {m68k_op_cmp_32_pcix , 0xf1ff, 0xb0bb, 20}, + {m68k_op_cmp_32_i , 0xf1ff, 0xb0bc, 14}, + {m68k_op_cmpa_16_aw , 0xf1ff, 0xb0f8, 14}, + {m68k_op_cmpa_16_al , 0xf1ff, 0xb0f9, 18}, + {m68k_op_cmpa_16_pcdi , 0xf1ff, 0xb0fa, 14}, + {m68k_op_cmpa_16_pcix , 0xf1ff, 0xb0fb, 16}, + {m68k_op_cmpa_16_i , 0xf1ff, 0xb0fc, 10}, + {m68k_op_cmpm_8_ay7 , 0xf1ff, 0xb10f, 12}, + {m68k_op_eor_8_pi7 , 0xf1ff, 0xb11f, 12}, + {m68k_op_eor_8_pd7 , 0xf1ff, 0xb127, 14}, + {m68k_op_eor_8_aw , 0xf1ff, 0xb138, 16}, + {m68k_op_eor_8_al , 0xf1ff, 0xb139, 20}, + {m68k_op_eor_16_aw , 0xf1ff, 0xb178, 16}, + {m68k_op_eor_16_al , 0xf1ff, 0xb179, 20}, + {m68k_op_eor_32_aw , 0xf1ff, 0xb1b8, 24}, + {m68k_op_eor_32_al , 0xf1ff, 0xb1b9, 28}, + {m68k_op_cmpa_32_aw , 0xf1ff, 0xb1f8, 18}, + {m68k_op_cmpa_32_al , 0xf1ff, 0xb1f9, 22}, + {m68k_op_cmpa_32_pcdi , 0xf1ff, 0xb1fa, 18}, + {m68k_op_cmpa_32_pcix , 0xf1ff, 0xb1fb, 20}, + {m68k_op_cmpa_32_i , 0xf1ff, 0xb1fc, 14}, + {m68k_op_and_8_er_pi7 , 0xf1ff, 0xc01f, 8}, + {m68k_op_and_8_er_pd7 , 0xf1ff, 0xc027, 10}, + {m68k_op_and_8_er_aw , 0xf1ff, 0xc038, 12}, + {m68k_op_and_8_er_al , 0xf1ff, 0xc039, 16}, + {m68k_op_and_8_er_pcdi , 0xf1ff, 0xc03a, 12}, + {m68k_op_and_8_er_pcix , 0xf1ff, 0xc03b, 14}, + {m68k_op_and_8_er_i , 0xf1ff, 0xc03c, 8}, + {m68k_op_and_16_er_aw , 0xf1ff, 0xc078, 12}, + {m68k_op_and_16_er_al , 0xf1ff, 0xc079, 16}, + {m68k_op_and_16_er_pcdi , 0xf1ff, 0xc07a, 12}, + {m68k_op_and_16_er_pcix , 0xf1ff, 0xc07b, 14}, + {m68k_op_and_16_er_i , 0xf1ff, 0xc07c, 8}, + {m68k_op_and_32_er_aw , 0xf1ff, 0xc0b8, 18}, + {m68k_op_and_32_er_al , 0xf1ff, 0xc0b9, 22}, + {m68k_op_and_32_er_pcdi , 0xf1ff, 0xc0ba, 18}, + {m68k_op_and_32_er_pcix , 0xf1ff, 0xc0bb, 20}, + {m68k_op_and_32_er_i , 0xf1ff, 0xc0bc, 16}, + {m68k_op_mulu_16_aw , 0xf1ff, 0xc0f8, 8}, + {m68k_op_mulu_16_al , 0xf1ff, 0xc0f9, 12}, + {m68k_op_mulu_16_pcdi , 0xf1ff, 0xc0fa, 8}, + {m68k_op_mulu_16_pcix , 0xf1ff, 0xc0fb, 10}, + {m68k_op_mulu_16_i , 0xf1ff, 0xc0fc, 4}, + {m68k_op_abcd_8_mm_ay7 , 0xf1ff, 0xc10f, 18}, + {m68k_op_and_8_re_pi7 , 0xf1ff, 0xc11f, 12}, + {m68k_op_and_8_re_pd7 , 0xf1ff, 0xc127, 14}, + {m68k_op_and_8_re_aw , 0xf1ff, 0xc138, 16}, + {m68k_op_and_8_re_al , 0xf1ff, 0xc139, 20}, + {m68k_op_and_16_re_aw , 0xf1ff, 0xc178, 16}, + {m68k_op_and_16_re_al , 0xf1ff, 0xc179, 20}, + {m68k_op_and_32_re_aw , 0xf1ff, 0xc1b8, 24}, + {m68k_op_and_32_re_al , 0xf1ff, 0xc1b9, 28}, + {m68k_op_muls_16_aw , 0xf1ff, 0xc1f8, 8}, + {m68k_op_muls_16_al , 0xf1ff, 0xc1f9, 12}, + {m68k_op_muls_16_pcdi , 0xf1ff, 0xc1fa, 8}, + {m68k_op_muls_16_pcix , 0xf1ff, 0xc1fb, 10}, + {m68k_op_muls_16_i , 0xf1ff, 0xc1fc, 4}, + {m68k_op_add_8_er_pi7 , 0xf1ff, 0xd01f, 8}, + {m68k_op_add_8_er_pd7 , 0xf1ff, 0xd027, 10}, + {m68k_op_add_8_er_aw , 0xf1ff, 0xd038, 12}, + {m68k_op_add_8_er_al , 0xf1ff, 0xd039, 16}, + {m68k_op_add_8_er_pcdi , 0xf1ff, 0xd03a, 12}, + {m68k_op_add_8_er_pcix , 0xf1ff, 0xd03b, 14}, + {m68k_op_add_8_er_i , 0xf1ff, 0xd03c, 8}, + {m68k_op_add_16_er_aw , 0xf1ff, 0xd078, 12}, + {m68k_op_add_16_er_al , 0xf1ff, 0xd079, 16}, + {m68k_op_add_16_er_pcdi , 0xf1ff, 0xd07a, 12}, + {m68k_op_add_16_er_pcix , 0xf1ff, 0xd07b, 14}, + {m68k_op_add_16_er_i , 0xf1ff, 0xd07c, 8}, + {m68k_op_add_32_er_aw , 0xf1ff, 0xd0b8, 18}, + {m68k_op_add_32_er_al , 0xf1ff, 0xd0b9, 22}, + {m68k_op_add_32_er_pcdi , 0xf1ff, 0xd0ba, 18}, + {m68k_op_add_32_er_pcix , 0xf1ff, 0xd0bb, 20}, + {m68k_op_add_32_er_i , 0xf1ff, 0xd0bc, 16}, + {m68k_op_adda_16_aw , 0xf1ff, 0xd0f8, 16}, + {m68k_op_adda_16_al , 0xf1ff, 0xd0f9, 20}, + {m68k_op_adda_16_pcdi , 0xf1ff, 0xd0fa, 16}, + {m68k_op_adda_16_pcix , 0xf1ff, 0xd0fb, 18}, + {m68k_op_adda_16_i , 0xf1ff, 0xd0fc, 12}, + {m68k_op_addx_8_mm_ay7 , 0xf1ff, 0xd10f, 18}, + {m68k_op_add_8_re_pi7 , 0xf1ff, 0xd11f, 12}, + {m68k_op_add_8_re_pd7 , 0xf1ff, 0xd127, 14}, + {m68k_op_add_8_re_aw , 0xf1ff, 0xd138, 16}, + {m68k_op_add_8_re_al , 0xf1ff, 0xd139, 20}, + {m68k_op_add_16_re_aw , 0xf1ff, 0xd178, 16}, + {m68k_op_add_16_re_al , 0xf1ff, 0xd179, 20}, + {m68k_op_add_32_re_aw , 0xf1ff, 0xd1b8, 24}, + {m68k_op_add_32_re_al , 0xf1ff, 0xd1b9, 28}, + {m68k_op_adda_32_aw , 0xf1ff, 0xd1f8, 18}, + {m68k_op_adda_32_al , 0xf1ff, 0xd1f9, 22}, + {m68k_op_adda_32_pcdi , 0xf1ff, 0xd1fa, 18}, + {m68k_op_adda_32_pcix , 0xf1ff, 0xd1fb, 20}, + {m68k_op_adda_32_i , 0xf1ff, 0xd1fc, 16}, + {m68k_op_ori_8_d , 0xfff8, 0x0000, 8}, + {m68k_op_ori_8_ai , 0xfff8, 0x0010, 16}, + {m68k_op_ori_8_pi , 0xfff8, 0x0018, 16}, + {m68k_op_ori_8_pd , 0xfff8, 0x0020, 18}, + {m68k_op_ori_8_di , 0xfff8, 0x0028, 20}, + {m68k_op_ori_8_ix , 0xfff8, 0x0030, 22}, + {m68k_op_ori_16_d , 0xfff8, 0x0040, 8}, + {m68k_op_ori_16_ai , 0xfff8, 0x0050, 16}, + {m68k_op_ori_16_pi , 0xfff8, 0x0058, 16}, + {m68k_op_ori_16_pd , 0xfff8, 0x0060, 18}, + {m68k_op_ori_16_di , 0xfff8, 0x0068, 20}, + {m68k_op_ori_16_ix , 0xfff8, 0x0070, 22}, + {m68k_op_ori_32_d , 0xfff8, 0x0080, 16}, + {m68k_op_ori_32_ai , 0xfff8, 0x0090, 28}, + {m68k_op_ori_32_pi , 0xfff8, 0x0098, 28}, + {m68k_op_ori_32_pd , 0xfff8, 0x00a0, 30}, + {m68k_op_ori_32_di , 0xfff8, 0x00a8, 32}, + {m68k_op_ori_32_ix , 0xfff8, 0x00b0, 34}, + {m68k_op_andi_8_d , 0xfff8, 0x0200, 8}, + {m68k_op_andi_8_ai , 0xfff8, 0x0210, 16}, + {m68k_op_andi_8_pi , 0xfff8, 0x0218, 16}, + {m68k_op_andi_8_pd , 0xfff8, 0x0220, 18}, + {m68k_op_andi_8_di , 0xfff8, 0x0228, 20}, + {m68k_op_andi_8_ix , 0xfff8, 0x0230, 22}, + {m68k_op_andi_16_d , 0xfff8, 0x0240, 8}, + {m68k_op_andi_16_ai , 0xfff8, 0x0250, 16}, + {m68k_op_andi_16_pi , 0xfff8, 0x0258, 16}, + {m68k_op_andi_16_pd , 0xfff8, 0x0260, 18}, + {m68k_op_andi_16_di , 0xfff8, 0x0268, 20}, + {m68k_op_andi_16_ix , 0xfff8, 0x0270, 22}, + {m68k_op_andi_32_d , 0xfff8, 0x0280, 14}, + {m68k_op_andi_32_ai , 0xfff8, 0x0290, 28}, + {m68k_op_andi_32_pi , 0xfff8, 0x0298, 28}, + {m68k_op_andi_32_pd , 0xfff8, 0x02a0, 30}, + {m68k_op_andi_32_di , 0xfff8, 0x02a8, 32}, + {m68k_op_andi_32_ix , 0xfff8, 0x02b0, 34}, + {m68k_op_subi_8_d , 0xfff8, 0x0400, 8}, + {m68k_op_subi_8_ai , 0xfff8, 0x0410, 16}, + {m68k_op_subi_8_pi , 0xfff8, 0x0418, 16}, + {m68k_op_subi_8_pd , 0xfff8, 0x0420, 18}, + {m68k_op_subi_8_di , 0xfff8, 0x0428, 20}, + {m68k_op_subi_8_ix , 0xfff8, 0x0430, 22}, + {m68k_op_subi_16_d , 0xfff8, 0x0440, 8}, + {m68k_op_subi_16_ai , 0xfff8, 0x0450, 16}, + {m68k_op_subi_16_pi , 0xfff8, 0x0458, 16}, + {m68k_op_subi_16_pd , 0xfff8, 0x0460, 18}, + {m68k_op_subi_16_di , 0xfff8, 0x0468, 20}, + {m68k_op_subi_16_ix , 0xfff8, 0x0470, 22}, + {m68k_op_subi_32_d , 0xfff8, 0x0480, 16}, + {m68k_op_subi_32_ai , 0xfff8, 0x0490, 28}, + {m68k_op_subi_32_pi , 0xfff8, 0x0498, 28}, + {m68k_op_subi_32_pd , 0xfff8, 0x04a0, 30}, + {m68k_op_subi_32_di , 0xfff8, 0x04a8, 32}, + {m68k_op_subi_32_ix , 0xfff8, 0x04b0, 34}, + {m68k_op_addi_8_d , 0xfff8, 0x0600, 8}, + {m68k_op_addi_8_ai , 0xfff8, 0x0610, 16}, + {m68k_op_addi_8_pi , 0xfff8, 0x0618, 16}, + {m68k_op_addi_8_pd , 0xfff8, 0x0620, 18}, + {m68k_op_addi_8_di , 0xfff8, 0x0628, 20}, + {m68k_op_addi_8_ix , 0xfff8, 0x0630, 22}, + {m68k_op_addi_16_d , 0xfff8, 0x0640, 8}, + {m68k_op_addi_16_ai , 0xfff8, 0x0650, 16}, + {m68k_op_addi_16_pi , 0xfff8, 0x0658, 16}, + {m68k_op_addi_16_pd , 0xfff8, 0x0660, 18}, + {m68k_op_addi_16_di , 0xfff8, 0x0668, 20}, + {m68k_op_addi_16_ix , 0xfff8, 0x0670, 22}, + {m68k_op_addi_32_d , 0xfff8, 0x0680, 16}, + {m68k_op_addi_32_ai , 0xfff8, 0x0690, 28}, + {m68k_op_addi_32_pi , 0xfff8, 0x0698, 28}, + {m68k_op_addi_32_pd , 0xfff8, 0x06a0, 30}, + {m68k_op_addi_32_di , 0xfff8, 0x06a8, 32}, + {m68k_op_addi_32_ix , 0xfff8, 0x06b0, 34}, + {m68k_op_btst_32_s_d , 0xfff8, 0x0800, 10}, + {m68k_op_btst_8_s_ai , 0xfff8, 0x0810, 12}, + {m68k_op_btst_8_s_pi , 0xfff8, 0x0818, 12}, + {m68k_op_btst_8_s_pd , 0xfff8, 0x0820, 14}, + {m68k_op_btst_8_s_di , 0xfff8, 0x0828, 16}, + {m68k_op_btst_8_s_ix , 0xfff8, 0x0830, 18}, + {m68k_op_bchg_32_s_d , 0xfff8, 0x0840, 12}, + {m68k_op_bchg_8_s_ai , 0xfff8, 0x0850, 16}, + {m68k_op_bchg_8_s_pi , 0xfff8, 0x0858, 16}, + {m68k_op_bchg_8_s_pd , 0xfff8, 0x0860, 18}, + {m68k_op_bchg_8_s_di , 0xfff8, 0x0868, 20}, + {m68k_op_bchg_8_s_ix , 0xfff8, 0x0870, 22}, + {m68k_op_bclr_32_s_d , 0xfff8, 0x0880, 14}, + {m68k_op_bclr_8_s_ai , 0xfff8, 0x0890, 16}, + {m68k_op_bclr_8_s_pi , 0xfff8, 0x0898, 16}, + {m68k_op_bclr_8_s_pd , 0xfff8, 0x08a0, 18}, + {m68k_op_bclr_8_s_di , 0xfff8, 0x08a8, 20}, + {m68k_op_bclr_8_s_ix , 0xfff8, 0x08b0, 22}, + {m68k_op_bset_32_s_d , 0xfff8, 0x08c0, 12}, + {m68k_op_bset_8_s_ai , 0xfff8, 0x08d0, 16}, + {m68k_op_bset_8_s_pi , 0xfff8, 0x08d8, 16}, + {m68k_op_bset_8_s_pd , 0xfff8, 0x08e0, 18}, + {m68k_op_bset_8_s_di , 0xfff8, 0x08e8, 20}, + {m68k_op_bset_8_s_ix , 0xfff8, 0x08f0, 22}, + {m68k_op_eori_8_d , 0xfff8, 0x0a00, 8}, + {m68k_op_eori_8_ai , 0xfff8, 0x0a10, 16}, + {m68k_op_eori_8_pi , 0xfff8, 0x0a18, 16}, + {m68k_op_eori_8_pd , 0xfff8, 0x0a20, 18}, + {m68k_op_eori_8_di , 0xfff8, 0x0a28, 20}, + {m68k_op_eori_8_ix , 0xfff8, 0x0a30, 22}, + {m68k_op_eori_16_d , 0xfff8, 0x0a40, 8}, + {m68k_op_eori_16_ai , 0xfff8, 0x0a50, 16}, + {m68k_op_eori_16_pi , 0xfff8, 0x0a58, 16}, + {m68k_op_eori_16_pd , 0xfff8, 0x0a60, 18}, + {m68k_op_eori_16_di , 0xfff8, 0x0a68, 20}, + {m68k_op_eori_16_ix , 0xfff8, 0x0a70, 22}, + {m68k_op_eori_32_d , 0xfff8, 0x0a80, 16}, + {m68k_op_eori_32_ai , 0xfff8, 0x0a90, 28}, + {m68k_op_eori_32_pi , 0xfff8, 0x0a98, 28}, + {m68k_op_eori_32_pd , 0xfff8, 0x0aa0, 30}, + {m68k_op_eori_32_di , 0xfff8, 0x0aa8, 32}, + {m68k_op_eori_32_ix , 0xfff8, 0x0ab0, 34}, + {m68k_op_cmpi_8_d , 0xfff8, 0x0c00, 8}, + {m68k_op_cmpi_8_ai , 0xfff8, 0x0c10, 12}, + {m68k_op_cmpi_8_pi , 0xfff8, 0x0c18, 12}, + {m68k_op_cmpi_8_pd , 0xfff8, 0x0c20, 14}, + {m68k_op_cmpi_8_di , 0xfff8, 0x0c28, 16}, + {m68k_op_cmpi_8_ix , 0xfff8, 0x0c30, 18}, + {m68k_op_cmpi_16_d , 0xfff8, 0x0c40, 8}, + {m68k_op_cmpi_16_ai , 0xfff8, 0x0c50, 12}, + {m68k_op_cmpi_16_pi , 0xfff8, 0x0c58, 12}, + {m68k_op_cmpi_16_pd , 0xfff8, 0x0c60, 14}, + {m68k_op_cmpi_16_di , 0xfff8, 0x0c68, 16}, + {m68k_op_cmpi_16_ix , 0xfff8, 0x0c70, 18}, + {m68k_op_cmpi_32_d , 0xfff8, 0x0c80, 14}, + {m68k_op_cmpi_32_ai , 0xfff8, 0x0c90, 20}, + {m68k_op_cmpi_32_pi , 0xfff8, 0x0c98, 20}, + {m68k_op_cmpi_32_pd , 0xfff8, 0x0ca0, 22}, + {m68k_op_cmpi_32_di , 0xfff8, 0x0ca8, 24}, + {m68k_op_cmpi_32_ix , 0xfff8, 0x0cb0, 26}, + {m68k_op_move_8_aw_d , 0xfff8, 0x11c0, 12}, + {m68k_op_move_8_aw_ai , 0xfff8, 0x11d0, 16}, + {m68k_op_move_8_aw_pi , 0xfff8, 0x11d8, 16}, + {m68k_op_move_8_aw_pd , 0xfff8, 0x11e0, 18}, + {m68k_op_move_8_aw_di , 0xfff8, 0x11e8, 20}, + {m68k_op_move_8_aw_ix , 0xfff8, 0x11f0, 22}, + {m68k_op_move_8_al_d , 0xfff8, 0x13c0, 16}, + {m68k_op_move_8_al_ai , 0xfff8, 0x13d0, 20}, + {m68k_op_move_8_al_pi , 0xfff8, 0x13d8, 20}, + {m68k_op_move_8_al_pd , 0xfff8, 0x13e0, 22}, + {m68k_op_move_8_al_di , 0xfff8, 0x13e8, 24}, + {m68k_op_move_8_al_ix , 0xfff8, 0x13f0, 26}, + {m68k_op_move_8_pi7_d , 0xfff8, 0x1ec0, 8}, + {m68k_op_move_8_pi7_ai , 0xfff8, 0x1ed0, 12}, + {m68k_op_move_8_pi7_pi , 0xfff8, 0x1ed8, 12}, + {m68k_op_move_8_pi7_pd , 0xfff8, 0x1ee0, 14}, + {m68k_op_move_8_pi7_di , 0xfff8, 0x1ee8, 16}, + {m68k_op_move_8_pi7_ix , 0xfff8, 0x1ef0, 18}, + {m68k_op_move_8_pd7_d , 0xfff8, 0x1f00, 8}, + {m68k_op_move_8_pd7_ai , 0xfff8, 0x1f10, 12}, + {m68k_op_move_8_pd7_pi , 0xfff8, 0x1f18, 12}, + {m68k_op_move_8_pd7_pd , 0xfff8, 0x1f20, 14}, + {m68k_op_move_8_pd7_di , 0xfff8, 0x1f28, 16}, + {m68k_op_move_8_pd7_ix , 0xfff8, 0x1f30, 18}, + {m68k_op_move_32_aw_d , 0xfff8, 0x21c0, 16}, + {m68k_op_move_32_aw_a , 0xfff8, 0x21c8, 16}, + {m68k_op_move_32_aw_ai , 0xfff8, 0x21d0, 24}, + {m68k_op_move_32_aw_pi , 0xfff8, 0x21d8, 24}, + {m68k_op_move_32_aw_pd , 0xfff8, 0x21e0, 26}, + {m68k_op_move_32_aw_di , 0xfff8, 0x21e8, 28}, + {m68k_op_move_32_aw_ix , 0xfff8, 0x21f0, 30}, + {m68k_op_move_32_al_d , 0xfff8, 0x23c0, 20}, + {m68k_op_move_32_al_a , 0xfff8, 0x23c8, 20}, + {m68k_op_move_32_al_ai , 0xfff8, 0x23d0, 28}, + {m68k_op_move_32_al_pi , 0xfff8, 0x23d8, 28}, + {m68k_op_move_32_al_pd , 0xfff8, 0x23e0, 30}, + {m68k_op_move_32_al_di , 0xfff8, 0x23e8, 32}, + {m68k_op_move_32_al_ix , 0xfff8, 0x23f0, 34}, + {m68k_op_move_16_aw_d , 0xfff8, 0x31c0, 12}, + {m68k_op_move_16_aw_a , 0xfff8, 0x31c8, 12}, + {m68k_op_move_16_aw_ai , 0xfff8, 0x31d0, 16}, + {m68k_op_move_16_aw_pi , 0xfff8, 0x31d8, 16}, + {m68k_op_move_16_aw_pd , 0xfff8, 0x31e0, 18}, + {m68k_op_move_16_aw_di , 0xfff8, 0x31e8, 20}, + {m68k_op_move_16_aw_ix , 0xfff8, 0x31f0, 22}, + {m68k_op_move_16_al_d , 0xfff8, 0x33c0, 16}, + {m68k_op_move_16_al_a , 0xfff8, 0x33c8, 16}, + {m68k_op_move_16_al_ai , 0xfff8, 0x33d0, 20}, + {m68k_op_move_16_al_pi , 0xfff8, 0x33d8, 20}, + {m68k_op_move_16_al_pd , 0xfff8, 0x33e0, 22}, + {m68k_op_move_16_al_di , 0xfff8, 0x33e8, 24}, + {m68k_op_move_16_al_ix , 0xfff8, 0x33f0, 26}, + {m68k_op_negx_8_d , 0xfff8, 0x4000, 4}, + {m68k_op_negx_8_ai , 0xfff8, 0x4010, 12}, + {m68k_op_negx_8_pi , 0xfff8, 0x4018, 12}, + {m68k_op_negx_8_pd , 0xfff8, 0x4020, 14}, + {m68k_op_negx_8_di , 0xfff8, 0x4028, 16}, + {m68k_op_negx_8_ix , 0xfff8, 0x4030, 18}, + {m68k_op_negx_16_d , 0xfff8, 0x4040, 4}, + {m68k_op_negx_16_ai , 0xfff8, 0x4050, 12}, + {m68k_op_negx_16_pi , 0xfff8, 0x4058, 12}, + {m68k_op_negx_16_pd , 0xfff8, 0x4060, 14}, + {m68k_op_negx_16_di , 0xfff8, 0x4068, 16}, + {m68k_op_negx_16_ix , 0xfff8, 0x4070, 18}, + {m68k_op_negx_32_d , 0xfff8, 0x4080, 6}, + {m68k_op_negx_32_ai , 0xfff8, 0x4090, 20}, + {m68k_op_negx_32_pi , 0xfff8, 0x4098, 20}, + {m68k_op_negx_32_pd , 0xfff8, 0x40a0, 22}, + {m68k_op_negx_32_di , 0xfff8, 0x40a8, 24}, + {m68k_op_negx_32_ix , 0xfff8, 0x40b0, 26}, + {m68k_op_move_16_frs_d , 0xfff8, 0x40c0, 6}, + {m68k_op_move_16_frs_ai , 0xfff8, 0x40d0, 12}, + {m68k_op_move_16_frs_pi , 0xfff8, 0x40d8, 12}, + {m68k_op_move_16_frs_pd , 0xfff8, 0x40e0, 14}, + {m68k_op_move_16_frs_di , 0xfff8, 0x40e8, 16}, + {m68k_op_move_16_frs_ix , 0xfff8, 0x40f0, 18}, + {m68k_op_clr_8_d , 0xfff8, 0x4200, 4}, + {m68k_op_clr_8_ai , 0xfff8, 0x4210, 12}, + {m68k_op_clr_8_pi , 0xfff8, 0x4218, 12}, + {m68k_op_clr_8_pd , 0xfff8, 0x4220, 14}, + {m68k_op_clr_8_di , 0xfff8, 0x4228, 16}, + {m68k_op_clr_8_ix , 0xfff8, 0x4230, 18}, + {m68k_op_clr_16_d , 0xfff8, 0x4240, 4}, + {m68k_op_clr_16_ai , 0xfff8, 0x4250, 12}, + {m68k_op_clr_16_pi , 0xfff8, 0x4258, 12}, + {m68k_op_clr_16_pd , 0xfff8, 0x4260, 14}, + {m68k_op_clr_16_di , 0xfff8, 0x4268, 16}, + {m68k_op_clr_16_ix , 0xfff8, 0x4270, 18}, + {m68k_op_clr_32_d , 0xfff8, 0x4280, 6}, + {m68k_op_clr_32_ai , 0xfff8, 0x4290, 20}, + {m68k_op_clr_32_pi , 0xfff8, 0x4298, 20}, + {m68k_op_clr_32_pd , 0xfff8, 0x42a0, 22}, + {m68k_op_clr_32_di , 0xfff8, 0x42a8, 24}, + {m68k_op_clr_32_ix , 0xfff8, 0x42b0, 26}, + {m68k_op_neg_8_d , 0xfff8, 0x4400, 4}, + {m68k_op_neg_8_ai , 0xfff8, 0x4410, 12}, + {m68k_op_neg_8_pi , 0xfff8, 0x4418, 12}, + {m68k_op_neg_8_pd , 0xfff8, 0x4420, 14}, + {m68k_op_neg_8_di , 0xfff8, 0x4428, 16}, + {m68k_op_neg_8_ix , 0xfff8, 0x4430, 18}, + {m68k_op_neg_16_d , 0xfff8, 0x4440, 4}, + {m68k_op_neg_16_ai , 0xfff8, 0x4450, 12}, + {m68k_op_neg_16_pi , 0xfff8, 0x4458, 12}, + {m68k_op_neg_16_pd , 0xfff8, 0x4460, 14}, + {m68k_op_neg_16_di , 0xfff8, 0x4468, 16}, + {m68k_op_neg_16_ix , 0xfff8, 0x4470, 18}, + {m68k_op_neg_32_d , 0xfff8, 0x4480, 6}, + {m68k_op_neg_32_ai , 0xfff8, 0x4490, 20}, + {m68k_op_neg_32_pi , 0xfff8, 0x4498, 20}, + {m68k_op_neg_32_pd , 0xfff8, 0x44a0, 22}, + {m68k_op_neg_32_di , 0xfff8, 0x44a8, 24}, + {m68k_op_neg_32_ix , 0xfff8, 0x44b0, 26}, + {m68k_op_move_16_toc_d , 0xfff8, 0x44c0, 12}, + {m68k_op_move_16_toc_ai , 0xfff8, 0x44d0, 16}, + {m68k_op_move_16_toc_pi , 0xfff8, 0x44d8, 16}, + {m68k_op_move_16_toc_pd , 0xfff8, 0x44e0, 18}, + {m68k_op_move_16_toc_di , 0xfff8, 0x44e8, 20}, + {m68k_op_move_16_toc_ix , 0xfff8, 0x44f0, 22}, + {m68k_op_not_8_d , 0xfff8, 0x4600, 4}, + {m68k_op_not_8_ai , 0xfff8, 0x4610, 12}, + {m68k_op_not_8_pi , 0xfff8, 0x4618, 12}, + {m68k_op_not_8_pd , 0xfff8, 0x4620, 14}, + {m68k_op_not_8_di , 0xfff8, 0x4628, 16}, + {m68k_op_not_8_ix , 0xfff8, 0x4630, 18}, + {m68k_op_not_16_d , 0xfff8, 0x4640, 4}, + {m68k_op_not_16_ai , 0xfff8, 0x4650, 12}, + {m68k_op_not_16_pi , 0xfff8, 0x4658, 12}, + {m68k_op_not_16_pd , 0xfff8, 0x4660, 14}, + {m68k_op_not_16_di , 0xfff8, 0x4668, 16}, + {m68k_op_not_16_ix , 0xfff8, 0x4670, 18}, + {m68k_op_not_32_d , 0xfff8, 0x4680, 6}, + {m68k_op_not_32_ai , 0xfff8, 0x4690, 20}, + {m68k_op_not_32_pi , 0xfff8, 0x4698, 20}, + {m68k_op_not_32_pd , 0xfff8, 0x46a0, 22}, + {m68k_op_not_32_di , 0xfff8, 0x46a8, 24}, + {m68k_op_not_32_ix , 0xfff8, 0x46b0, 26}, + {m68k_op_move_16_tos_d , 0xfff8, 0x46c0, 12}, + {m68k_op_move_16_tos_ai , 0xfff8, 0x46d0, 16}, + {m68k_op_move_16_tos_pi , 0xfff8, 0x46d8, 16}, + {m68k_op_move_16_tos_pd , 0xfff8, 0x46e0, 18}, + {m68k_op_move_16_tos_di , 0xfff8, 0x46e8, 20}, + {m68k_op_move_16_tos_ix , 0xfff8, 0x46f0, 22}, + {m68k_op_nbcd_8_d , 0xfff8, 0x4800, 6}, + {m68k_op_nbcd_8_ai , 0xfff8, 0x4810, 12}, + {m68k_op_nbcd_8_pi , 0xfff8, 0x4818, 12}, + {m68k_op_nbcd_8_pd , 0xfff8, 0x4820, 14}, + {m68k_op_nbcd_8_di , 0xfff8, 0x4828, 16}, + {m68k_op_nbcd_8_ix , 0xfff8, 0x4830, 18}, + {m68k_op_swap_32 , 0xfff8, 0x4840, 4}, + {m68k_op_pea_32_ai , 0xfff8, 0x4850, 12}, + {m68k_op_pea_32_di , 0xfff8, 0x4868, 16}, + {m68k_op_pea_32_ix , 0xfff8, 0x4870, 20}, + {m68k_op_ext_16 , 0xfff8, 0x4880, 4}, + {m68k_op_movem_16_re_ai , 0xfff8, 0x4890, 8}, + {m68k_op_movem_16_re_pd , 0xfff8, 0x48a0, 8}, + {m68k_op_movem_16_re_di , 0xfff8, 0x48a8, 12}, + {m68k_op_movem_16_re_ix , 0xfff8, 0x48b0, 14}, + {m68k_op_ext_32 , 0xfff8, 0x48c0, 4}, + {m68k_op_movem_32_re_ai , 0xfff8, 0x48d0, 8}, + {m68k_op_movem_32_re_pd , 0xfff8, 0x48e0, 8}, + {m68k_op_movem_32_re_di , 0xfff8, 0x48e8, 12}, + {m68k_op_movem_32_re_ix , 0xfff8, 0x48f0, 14}, + {m68k_op_tst_8_d , 0xfff8, 0x4a00, 4}, + {m68k_op_tst_8_ai , 0xfff8, 0x4a10, 8}, + {m68k_op_tst_8_pi , 0xfff8, 0x4a18, 8}, + {m68k_op_tst_8_pd , 0xfff8, 0x4a20, 10}, + {m68k_op_tst_8_di , 0xfff8, 0x4a28, 12}, + {m68k_op_tst_8_ix , 0xfff8, 0x4a30, 14}, + {m68k_op_tst_16_d , 0xfff8, 0x4a40, 4}, + {m68k_op_tst_16_ai , 0xfff8, 0x4a50, 8}, + {m68k_op_tst_16_pi , 0xfff8, 0x4a58, 8}, + {m68k_op_tst_16_pd , 0xfff8, 0x4a60, 10}, + {m68k_op_tst_16_di , 0xfff8, 0x4a68, 12}, + {m68k_op_tst_16_ix , 0xfff8, 0x4a70, 14}, + {m68k_op_tst_32_d , 0xfff8, 0x4a80, 4}, + {m68k_op_tst_32_ai , 0xfff8, 0x4a90, 12}, + {m68k_op_tst_32_pi , 0xfff8, 0x4a98, 12}, + {m68k_op_tst_32_pd , 0xfff8, 0x4aa0, 14}, + {m68k_op_tst_32_di , 0xfff8, 0x4aa8, 16}, + {m68k_op_tst_32_ix , 0xfff8, 0x4ab0, 18}, + {m68k_op_tas_8_d , 0xfff8, 0x4ac0, 4}, + {m68k_op_tas_8_ai , 0xfff8, 0x4ad0, 18}, + {m68k_op_tas_8_pi , 0xfff8, 0x4ad8, 18}, + {m68k_op_tas_8_pd , 0xfff8, 0x4ae0, 20}, + {m68k_op_tas_8_di , 0xfff8, 0x4ae8, 22}, + {m68k_op_tas_8_ix , 0xfff8, 0x4af0, 24}, + {m68k_op_movem_16_er_ai , 0xfff8, 0x4c90, 12}, + {m68k_op_movem_16_er_pi , 0xfff8, 0x4c98, 12}, + {m68k_op_movem_16_er_di , 0xfff8, 0x4ca8, 16}, + {m68k_op_movem_16_er_ix , 0xfff8, 0x4cb0, 18}, + {m68k_op_movem_32_er_ai , 0xfff8, 0x4cd0, 12}, + {m68k_op_movem_32_er_pi , 0xfff8, 0x4cd8, 12}, + {m68k_op_movem_32_er_di , 0xfff8, 0x4ce8, 16}, + {m68k_op_movem_32_er_ix , 0xfff8, 0x4cf0, 18}, + {m68k_op_link_16 , 0xfff8, 0x4e50, 16}, + {m68k_op_unlk_32 , 0xfff8, 0x4e58, 12}, + {m68k_op_move_32_tou , 0xfff8, 0x4e60, 4}, + {m68k_op_move_32_fru , 0xfff8, 0x4e68, 4}, + {m68k_op_jsr_32_ai , 0xfff8, 0x4e90, 16}, + {m68k_op_jsr_32_di , 0xfff8, 0x4ea8, 18}, + {m68k_op_jsr_32_ix , 0xfff8, 0x4eb0, 22}, + {m68k_op_jmp_32_ai , 0xfff8, 0x4ed0, 8}, + {m68k_op_jmp_32_di , 0xfff8, 0x4ee8, 10}, + {m68k_op_jmp_32_ix , 0xfff8, 0x4ef0, 14}, + {m68k_op_st_8_d , 0xfff8, 0x50c0, 6}, + {m68k_op_dbt_16 , 0xfff8, 0x50c8, 12}, + {m68k_op_st_8_ai , 0xfff8, 0x50d0, 12}, + {m68k_op_st_8_pi , 0xfff8, 0x50d8, 12}, + {m68k_op_st_8_pd , 0xfff8, 0x50e0, 14}, + {m68k_op_st_8_di , 0xfff8, 0x50e8, 16}, + {m68k_op_st_8_ix , 0xfff8, 0x50f0, 18}, + {m68k_op_sf_8_d , 0xfff8, 0x51c0, 4}, + {m68k_op_dbf_16 , 0xfff8, 0x51c8, 12}, + {m68k_op_sf_8_ai , 0xfff8, 0x51d0, 12}, + {m68k_op_sf_8_pi , 0xfff8, 0x51d8, 12}, + {m68k_op_sf_8_pd , 0xfff8, 0x51e0, 14}, + {m68k_op_sf_8_di , 0xfff8, 0x51e8, 16}, + {m68k_op_sf_8_ix , 0xfff8, 0x51f0, 18}, + {m68k_op_shi_8_d , 0xfff8, 0x52c0, 4}, + {m68k_op_dbhi_16 , 0xfff8, 0x52c8, 12}, + {m68k_op_shi_8_ai , 0xfff8, 0x52d0, 12}, + {m68k_op_shi_8_pi , 0xfff8, 0x52d8, 12}, + {m68k_op_shi_8_pd , 0xfff8, 0x52e0, 14}, + {m68k_op_shi_8_di , 0xfff8, 0x52e8, 16}, + {m68k_op_shi_8_ix , 0xfff8, 0x52f0, 18}, + {m68k_op_sls_8_d , 0xfff8, 0x53c0, 4}, + {m68k_op_dbls_16 , 0xfff8, 0x53c8, 12}, + {m68k_op_sls_8_ai , 0xfff8, 0x53d0, 12}, + {m68k_op_sls_8_pi , 0xfff8, 0x53d8, 12}, + {m68k_op_sls_8_pd , 0xfff8, 0x53e0, 14}, + {m68k_op_sls_8_di , 0xfff8, 0x53e8, 16}, + {m68k_op_sls_8_ix , 0xfff8, 0x53f0, 18}, + {m68k_op_scc_8_d , 0xfff8, 0x54c0, 4}, + {m68k_op_dbcc_16 , 0xfff8, 0x54c8, 12}, + {m68k_op_scc_8_ai , 0xfff8, 0x54d0, 12}, + {m68k_op_scc_8_pi , 0xfff8, 0x54d8, 12}, + {m68k_op_scc_8_pd , 0xfff8, 0x54e0, 14}, + {m68k_op_scc_8_di , 0xfff8, 0x54e8, 16}, + {m68k_op_scc_8_ix , 0xfff8, 0x54f0, 18}, + {m68k_op_scs_8_d , 0xfff8, 0x55c0, 4}, + {m68k_op_dbcs_16 , 0xfff8, 0x55c8, 12}, + {m68k_op_scs_8_ai , 0xfff8, 0x55d0, 12}, + {m68k_op_scs_8_pi , 0xfff8, 0x55d8, 12}, + {m68k_op_scs_8_pd , 0xfff8, 0x55e0, 14}, + {m68k_op_scs_8_di , 0xfff8, 0x55e8, 16}, + {m68k_op_scs_8_ix , 0xfff8, 0x55f0, 18}, + {m68k_op_sne_8_d , 0xfff8, 0x56c0, 4}, + {m68k_op_dbne_16 , 0xfff8, 0x56c8, 12}, + {m68k_op_sne_8_ai , 0xfff8, 0x56d0, 12}, + {m68k_op_sne_8_pi , 0xfff8, 0x56d8, 12}, + {m68k_op_sne_8_pd , 0xfff8, 0x56e0, 14}, + {m68k_op_sne_8_di , 0xfff8, 0x56e8, 16}, + {m68k_op_sne_8_ix , 0xfff8, 0x56f0, 18}, + {m68k_op_seq_8_d , 0xfff8, 0x57c0, 4}, + {m68k_op_dbeq_16 , 0xfff8, 0x57c8, 12}, + {m68k_op_seq_8_ai , 0xfff8, 0x57d0, 12}, + {m68k_op_seq_8_pi , 0xfff8, 0x57d8, 12}, + {m68k_op_seq_8_pd , 0xfff8, 0x57e0, 14}, + {m68k_op_seq_8_di , 0xfff8, 0x57e8, 16}, + {m68k_op_seq_8_ix , 0xfff8, 0x57f0, 18}, + {m68k_op_svc_8_d , 0xfff8, 0x58c0, 4}, + {m68k_op_dbvc_16 , 0xfff8, 0x58c8, 12}, + {m68k_op_svc_8_ai , 0xfff8, 0x58d0, 12}, + {m68k_op_svc_8_pi , 0xfff8, 0x58d8, 12}, + {m68k_op_svc_8_pd , 0xfff8, 0x58e0, 14}, + {m68k_op_svc_8_di , 0xfff8, 0x58e8, 16}, + {m68k_op_svc_8_ix , 0xfff8, 0x58f0, 18}, + {m68k_op_svs_8_d , 0xfff8, 0x59c0, 4}, + {m68k_op_dbvs_16 , 0xfff8, 0x59c8, 12}, + {m68k_op_svs_8_ai , 0xfff8, 0x59d0, 12}, + {m68k_op_svs_8_pi , 0xfff8, 0x59d8, 12}, + {m68k_op_svs_8_pd , 0xfff8, 0x59e0, 14}, + {m68k_op_svs_8_di , 0xfff8, 0x59e8, 16}, + {m68k_op_svs_8_ix , 0xfff8, 0x59f0, 18}, + {m68k_op_spl_8_d , 0xfff8, 0x5ac0, 4}, + {m68k_op_dbpl_16 , 0xfff8, 0x5ac8, 12}, + {m68k_op_spl_8_ai , 0xfff8, 0x5ad0, 12}, + {m68k_op_spl_8_pi , 0xfff8, 0x5ad8, 12}, + {m68k_op_spl_8_pd , 0xfff8, 0x5ae0, 14}, + {m68k_op_spl_8_di , 0xfff8, 0x5ae8, 16}, + {m68k_op_spl_8_ix , 0xfff8, 0x5af0, 18}, + {m68k_op_smi_8_d , 0xfff8, 0x5bc0, 4}, + {m68k_op_dbmi_16 , 0xfff8, 0x5bc8, 12}, + {m68k_op_smi_8_ai , 0xfff8, 0x5bd0, 12}, + {m68k_op_smi_8_pi , 0xfff8, 0x5bd8, 12}, + {m68k_op_smi_8_pd , 0xfff8, 0x5be0, 14}, + {m68k_op_smi_8_di , 0xfff8, 0x5be8, 16}, + {m68k_op_smi_8_ix , 0xfff8, 0x5bf0, 18}, + {m68k_op_sge_8_d , 0xfff8, 0x5cc0, 4}, + {m68k_op_dbge_16 , 0xfff8, 0x5cc8, 12}, + {m68k_op_sge_8_ai , 0xfff8, 0x5cd0, 12}, + {m68k_op_sge_8_pi , 0xfff8, 0x5cd8, 12}, + {m68k_op_sge_8_pd , 0xfff8, 0x5ce0, 14}, + {m68k_op_sge_8_di , 0xfff8, 0x5ce8, 16}, + {m68k_op_sge_8_ix , 0xfff8, 0x5cf0, 18}, + {m68k_op_slt_8_d , 0xfff8, 0x5dc0, 4}, + {m68k_op_dblt_16 , 0xfff8, 0x5dc8, 12}, + {m68k_op_slt_8_ai , 0xfff8, 0x5dd0, 12}, + {m68k_op_slt_8_pi , 0xfff8, 0x5dd8, 12}, + {m68k_op_slt_8_pd , 0xfff8, 0x5de0, 14}, + {m68k_op_slt_8_di , 0xfff8, 0x5de8, 16}, + {m68k_op_slt_8_ix , 0xfff8, 0x5df0, 18}, + {m68k_op_sgt_8_d , 0xfff8, 0x5ec0, 4}, + {m68k_op_dbgt_16 , 0xfff8, 0x5ec8, 12}, + {m68k_op_sgt_8_ai , 0xfff8, 0x5ed0, 12}, + {m68k_op_sgt_8_pi , 0xfff8, 0x5ed8, 12}, + {m68k_op_sgt_8_pd , 0xfff8, 0x5ee0, 14}, + {m68k_op_sgt_8_di , 0xfff8, 0x5ee8, 16}, + {m68k_op_sgt_8_ix , 0xfff8, 0x5ef0, 18}, + {m68k_op_sle_8_d , 0xfff8, 0x5fc0, 4}, + {m68k_op_dble_16 , 0xfff8, 0x5fc8, 12}, + {m68k_op_sle_8_ai , 0xfff8, 0x5fd0, 12}, + {m68k_op_sle_8_pi , 0xfff8, 0x5fd8, 12}, + {m68k_op_sle_8_pd , 0xfff8, 0x5fe0, 14}, + {m68k_op_sle_8_di , 0xfff8, 0x5fe8, 16}, + {m68k_op_sle_8_ix , 0xfff8, 0x5ff0, 18}, + {m68k_op_sbcd_8_mm_ax7 , 0xfff8, 0x8f08, 18}, + {m68k_op_subx_8_mm_ax7 , 0xfff8, 0x9f08, 18}, + {m68k_op_cmpm_8_ax7 , 0xfff8, 0xbf08, 12}, + {m68k_op_abcd_8_mm_ax7 , 0xfff8, 0xcf08, 18}, + {m68k_op_addx_8_mm_ax7 , 0xfff8, 0xdf08, 18}, + {m68k_op_asr_16_ai , 0xfff8, 0xe0d0, 12}, + {m68k_op_asr_16_pi , 0xfff8, 0xe0d8, 12}, + {m68k_op_asr_16_pd , 0xfff8, 0xe0e0, 14}, + {m68k_op_asr_16_di , 0xfff8, 0xe0e8, 16}, + {m68k_op_asr_16_ix , 0xfff8, 0xe0f0, 18}, + {m68k_op_asl_16_ai , 0xfff8, 0xe1d0, 12}, + {m68k_op_asl_16_pi , 0xfff8, 0xe1d8, 12}, + {m68k_op_asl_16_pd , 0xfff8, 0xe1e0, 14}, + {m68k_op_asl_16_di , 0xfff8, 0xe1e8, 16}, + {m68k_op_asl_16_ix , 0xfff8, 0xe1f0, 18}, + {m68k_op_lsr_16_ai , 0xfff8, 0xe2d0, 12}, + {m68k_op_lsr_16_pi , 0xfff8, 0xe2d8, 12}, + {m68k_op_lsr_16_pd , 0xfff8, 0xe2e0, 14}, + {m68k_op_lsr_16_di , 0xfff8, 0xe2e8, 16}, + {m68k_op_lsr_16_ix , 0xfff8, 0xe2f0, 18}, + {m68k_op_lsl_16_ai , 0xfff8, 0xe3d0, 12}, + {m68k_op_lsl_16_pi , 0xfff8, 0xe3d8, 12}, + {m68k_op_lsl_16_pd , 0xfff8, 0xe3e0, 14}, + {m68k_op_lsl_16_di , 0xfff8, 0xe3e8, 16}, + {m68k_op_lsl_16_ix , 0xfff8, 0xe3f0, 18}, + {m68k_op_roxr_16_ai , 0xfff8, 0xe4d0, 12}, + {m68k_op_roxr_16_pi , 0xfff8, 0xe4d8, 12}, + {m68k_op_roxr_16_pd , 0xfff8, 0xe4e0, 14}, + {m68k_op_roxr_16_di , 0xfff8, 0xe4e8, 16}, + {m68k_op_roxr_16_ix , 0xfff8, 0xe4f0, 18}, + {m68k_op_roxl_16_ai , 0xfff8, 0xe5d0, 12}, + {m68k_op_roxl_16_pi , 0xfff8, 0xe5d8, 12}, + {m68k_op_roxl_16_pd , 0xfff8, 0xe5e0, 14}, + {m68k_op_roxl_16_di , 0xfff8, 0xe5e8, 16}, + {m68k_op_roxl_16_ix , 0xfff8, 0xe5f0, 18}, + {m68k_op_ror_16_ai , 0xfff8, 0xe6d0, 12}, + {m68k_op_ror_16_pi , 0xfff8, 0xe6d8, 12}, + {m68k_op_ror_16_pd , 0xfff8, 0xe6e0, 14}, + {m68k_op_ror_16_di , 0xfff8, 0xe6e8, 16}, + {m68k_op_ror_16_ix , 0xfff8, 0xe6f0, 18}, + {m68k_op_rol_16_ai , 0xfff8, 0xe7d0, 12}, + {m68k_op_rol_16_pi , 0xfff8, 0xe7d8, 12}, + {m68k_op_rol_16_pd , 0xfff8, 0xe7e0, 14}, + {m68k_op_rol_16_di , 0xfff8, 0xe7e8, 16}, + {m68k_op_rol_16_ix , 0xfff8, 0xe7f0, 18}, + {m68k_op_ori_8_pi7 , 0xffff, 0x001f, 16}, + {m68k_op_ori_8_pd7 , 0xffff, 0x0027, 18}, + {m68k_op_ori_8_aw , 0xffff, 0x0038, 20}, + {m68k_op_ori_8_al , 0xffff, 0x0039, 24}, + {m68k_op_ori_16_toc , 0xffff, 0x003c, 20}, + {m68k_op_ori_16_aw , 0xffff, 0x0078, 20}, + {m68k_op_ori_16_al , 0xffff, 0x0079, 24}, + {m68k_op_ori_16_tos , 0xffff, 0x007c, 20}, + {m68k_op_ori_32_aw , 0xffff, 0x00b8, 32}, + {m68k_op_ori_32_al , 0xffff, 0x00b9, 36}, + {m68k_op_andi_8_pi7 , 0xffff, 0x021f, 16}, + {m68k_op_andi_8_pd7 , 0xffff, 0x0227, 18}, + {m68k_op_andi_8_aw , 0xffff, 0x0238, 20}, + {m68k_op_andi_8_al , 0xffff, 0x0239, 24}, + {m68k_op_andi_16_toc , 0xffff, 0x023c, 20}, + {m68k_op_andi_16_aw , 0xffff, 0x0278, 20}, + {m68k_op_andi_16_al , 0xffff, 0x0279, 24}, + {m68k_op_andi_16_tos , 0xffff, 0x027c, 20}, + {m68k_op_andi_32_aw , 0xffff, 0x02b8, 32}, + {m68k_op_andi_32_al , 0xffff, 0x02b9, 36}, + {m68k_op_subi_8_pi7 , 0xffff, 0x041f, 16}, + {m68k_op_subi_8_pd7 , 0xffff, 0x0427, 18}, + {m68k_op_subi_8_aw , 0xffff, 0x0438, 20}, + {m68k_op_subi_8_al , 0xffff, 0x0439, 24}, + {m68k_op_subi_16_aw , 0xffff, 0x0478, 20}, + {m68k_op_subi_16_al , 0xffff, 0x0479, 24}, + {m68k_op_subi_32_aw , 0xffff, 0x04b8, 32}, + {m68k_op_subi_32_al , 0xffff, 0x04b9, 36}, + {m68k_op_addi_8_pi7 , 0xffff, 0x061f, 16}, + {m68k_op_addi_8_pd7 , 0xffff, 0x0627, 18}, + {m68k_op_addi_8_aw , 0xffff, 0x0638, 20}, + {m68k_op_addi_8_al , 0xffff, 0x0639, 24}, + {m68k_op_addi_16_aw , 0xffff, 0x0678, 20}, + {m68k_op_addi_16_al , 0xffff, 0x0679, 24}, + {m68k_op_addi_32_aw , 0xffff, 0x06b8, 32}, + {m68k_op_addi_32_al , 0xffff, 0x06b9, 36}, + {m68k_op_btst_8_s_pi7 , 0xffff, 0x081f, 12}, + {m68k_op_btst_8_s_pd7 , 0xffff, 0x0827, 14}, + {m68k_op_btst_8_s_aw , 0xffff, 0x0838, 16}, + {m68k_op_btst_8_s_al , 0xffff, 0x0839, 20}, + {m68k_op_btst_8_s_pcdi , 0xffff, 0x083a, 16}, + {m68k_op_btst_8_s_pcix , 0xffff, 0x083b, 18}, + {m68k_op_bchg_8_s_pi7 , 0xffff, 0x085f, 16}, + {m68k_op_bchg_8_s_pd7 , 0xffff, 0x0867, 18}, + {m68k_op_bchg_8_s_aw , 0xffff, 0x0878, 20}, + {m68k_op_bchg_8_s_al , 0xffff, 0x0879, 24}, + {m68k_op_bclr_8_s_pi7 , 0xffff, 0x089f, 16}, + {m68k_op_bclr_8_s_pd7 , 0xffff, 0x08a7, 18}, + {m68k_op_bclr_8_s_aw , 0xffff, 0x08b8, 20}, + {m68k_op_bclr_8_s_al , 0xffff, 0x08b9, 24}, + {m68k_op_bset_8_s_pi7 , 0xffff, 0x08df, 16}, + {m68k_op_bset_8_s_pd7 , 0xffff, 0x08e7, 18}, + {m68k_op_bset_8_s_aw , 0xffff, 0x08f8, 20}, + {m68k_op_bset_8_s_al , 0xffff, 0x08f9, 24}, + {m68k_op_eori_8_pi7 , 0xffff, 0x0a1f, 16}, + {m68k_op_eori_8_pd7 , 0xffff, 0x0a27, 18}, + {m68k_op_eori_8_aw , 0xffff, 0x0a38, 20}, + {m68k_op_eori_8_al , 0xffff, 0x0a39, 24}, + {m68k_op_eori_16_toc , 0xffff, 0x0a3c, 20}, + {m68k_op_eori_16_aw , 0xffff, 0x0a78, 20}, + {m68k_op_eori_16_al , 0xffff, 0x0a79, 24}, + {m68k_op_eori_16_tos , 0xffff, 0x0a7c, 20}, + {m68k_op_eori_32_aw , 0xffff, 0x0ab8, 32}, + {m68k_op_eori_32_al , 0xffff, 0x0ab9, 36}, + {m68k_op_cmpi_8_pi7 , 0xffff, 0x0c1f, 12}, + {m68k_op_cmpi_8_pd7 , 0xffff, 0x0c27, 14}, + {m68k_op_cmpi_8_aw , 0xffff, 0x0c38, 16}, + {m68k_op_cmpi_8_al , 0xffff, 0x0c39, 20}, + {m68k_op_cmpi_16_aw , 0xffff, 0x0c78, 16}, + {m68k_op_cmpi_16_al , 0xffff, 0x0c79, 20}, + {m68k_op_cmpi_32_aw , 0xffff, 0x0cb8, 24}, + {m68k_op_cmpi_32_al , 0xffff, 0x0cb9, 28}, + {m68k_op_move_8_aw_pi7 , 0xffff, 0x11df, 16}, + {m68k_op_move_8_aw_pd7 , 0xffff, 0x11e7, 18}, + {m68k_op_move_8_aw_aw , 0xffff, 0x11f8, 20}, + {m68k_op_move_8_aw_al , 0xffff, 0x11f9, 24}, + {m68k_op_move_8_aw_pcdi , 0xffff, 0x11fa, 20}, + {m68k_op_move_8_aw_pcix , 0xffff, 0x11fb, 22}, + {m68k_op_move_8_aw_i , 0xffff, 0x11fc, 16}, + {m68k_op_move_8_al_pi7 , 0xffff, 0x13df, 20}, + {m68k_op_move_8_al_pd7 , 0xffff, 0x13e7, 22}, + {m68k_op_move_8_al_aw , 0xffff, 0x13f8, 24}, + {m68k_op_move_8_al_al , 0xffff, 0x13f9, 28}, + {m68k_op_move_8_al_pcdi , 0xffff, 0x13fa, 24}, + {m68k_op_move_8_al_pcix , 0xffff, 0x13fb, 26}, + {m68k_op_move_8_al_i , 0xffff, 0x13fc, 20}, + {m68k_op_move_8_pi7_pi7 , 0xffff, 0x1edf, 12}, + {m68k_op_move_8_pi7_pd7 , 0xffff, 0x1ee7, 14}, + {m68k_op_move_8_pi7_aw , 0xffff, 0x1ef8, 16}, + {m68k_op_move_8_pi7_al , 0xffff, 0x1ef9, 20}, + {m68k_op_move_8_pi7_pcdi , 0xffff, 0x1efa, 16}, + {m68k_op_move_8_pi7_pcix , 0xffff, 0x1efb, 18}, + {m68k_op_move_8_pi7_i , 0xffff, 0x1efc, 12}, + {m68k_op_move_8_pd7_pi7 , 0xffff, 0x1f1f, 12}, + {m68k_op_move_8_pd7_pd7 , 0xffff, 0x1f27, 14}, + {m68k_op_move_8_pd7_aw , 0xffff, 0x1f38, 16}, + {m68k_op_move_8_pd7_al , 0xffff, 0x1f39, 20}, + {m68k_op_move_8_pd7_pcdi , 0xffff, 0x1f3a, 16}, + {m68k_op_move_8_pd7_pcix , 0xffff, 0x1f3b, 18}, + {m68k_op_move_8_pd7_i , 0xffff, 0x1f3c, 12}, + {m68k_op_move_32_aw_aw , 0xffff, 0x21f8, 28}, + {m68k_op_move_32_aw_al , 0xffff, 0x21f9, 32}, + {m68k_op_move_32_aw_pcdi , 0xffff, 0x21fa, 28}, + {m68k_op_move_32_aw_pcix , 0xffff, 0x21fb, 30}, + {m68k_op_move_32_aw_i , 0xffff, 0x21fc, 24}, + {m68k_op_move_32_al_aw , 0xffff, 0x23f8, 32}, + {m68k_op_move_32_al_al , 0xffff, 0x23f9, 36}, + {m68k_op_move_32_al_pcdi , 0xffff, 0x23fa, 32}, + {m68k_op_move_32_al_pcix , 0xffff, 0x23fb, 34}, + {m68k_op_move_32_al_i , 0xffff, 0x23fc, 28}, + {m68k_op_move_16_aw_aw , 0xffff, 0x31f8, 20}, + {m68k_op_move_16_aw_al , 0xffff, 0x31f9, 24}, + {m68k_op_move_16_aw_pcdi , 0xffff, 0x31fa, 20}, + {m68k_op_move_16_aw_pcix , 0xffff, 0x31fb, 22}, + {m68k_op_move_16_aw_i , 0xffff, 0x31fc, 16}, + {m68k_op_move_16_al_aw , 0xffff, 0x33f8, 24}, + {m68k_op_move_16_al_al , 0xffff, 0x33f9, 28}, + {m68k_op_move_16_al_pcdi , 0xffff, 0x33fa, 24}, + {m68k_op_move_16_al_pcix , 0xffff, 0x33fb, 26}, + {m68k_op_move_16_al_i , 0xffff, 0x33fc, 20}, + {m68k_op_negx_8_pi7 , 0xffff, 0x401f, 12}, + {m68k_op_negx_8_pd7 , 0xffff, 0x4027, 14}, + {m68k_op_negx_8_aw , 0xffff, 0x4038, 16}, + {m68k_op_negx_8_al , 0xffff, 0x4039, 20}, + {m68k_op_negx_16_aw , 0xffff, 0x4078, 16}, + {m68k_op_negx_16_al , 0xffff, 0x4079, 20}, + {m68k_op_negx_32_aw , 0xffff, 0x40b8, 24}, + {m68k_op_negx_32_al , 0xffff, 0x40b9, 28}, + {m68k_op_move_16_frs_aw , 0xffff, 0x40f8, 16}, + {m68k_op_move_16_frs_al , 0xffff, 0x40f9, 20}, + {m68k_op_clr_8_pi7 , 0xffff, 0x421f, 12}, + {m68k_op_clr_8_pd7 , 0xffff, 0x4227, 14}, + {m68k_op_clr_8_aw , 0xffff, 0x4238, 16}, + {m68k_op_clr_8_al , 0xffff, 0x4239, 20}, + {m68k_op_clr_16_aw , 0xffff, 0x4278, 16}, + {m68k_op_clr_16_al , 0xffff, 0x4279, 20}, + {m68k_op_clr_32_aw , 0xffff, 0x42b8, 24}, + {m68k_op_clr_32_al , 0xffff, 0x42b9, 28}, + {m68k_op_neg_8_pi7 , 0xffff, 0x441f, 12}, + {m68k_op_neg_8_pd7 , 0xffff, 0x4427, 14}, + {m68k_op_neg_8_aw , 0xffff, 0x4438, 16}, + {m68k_op_neg_8_al , 0xffff, 0x4439, 20}, + {m68k_op_neg_16_aw , 0xffff, 0x4478, 16}, + {m68k_op_neg_16_al , 0xffff, 0x4479, 20}, + {m68k_op_neg_32_aw , 0xffff, 0x44b8, 24}, + {m68k_op_neg_32_al , 0xffff, 0x44b9, 28}, + {m68k_op_move_16_toc_aw , 0xffff, 0x44f8, 20}, + {m68k_op_move_16_toc_al , 0xffff, 0x44f9, 24}, + {m68k_op_move_16_toc_pcdi , 0xffff, 0x44fa, 20}, + {m68k_op_move_16_toc_pcix , 0xffff, 0x44fb, 22}, + {m68k_op_move_16_toc_i , 0xffff, 0x44fc, 16}, + {m68k_op_not_8_pi7 , 0xffff, 0x461f, 12}, + {m68k_op_not_8_pd7 , 0xffff, 0x4627, 14}, + {m68k_op_not_8_aw , 0xffff, 0x4638, 16}, + {m68k_op_not_8_al , 0xffff, 0x4639, 20}, + {m68k_op_not_16_aw , 0xffff, 0x4678, 16}, + {m68k_op_not_16_al , 0xffff, 0x4679, 20}, + {m68k_op_not_32_aw , 0xffff, 0x46b8, 24}, + {m68k_op_not_32_al , 0xffff, 0x46b9, 28}, + {m68k_op_move_16_tos_aw , 0xffff, 0x46f8, 20}, + {m68k_op_move_16_tos_al , 0xffff, 0x46f9, 24}, + {m68k_op_move_16_tos_pcdi , 0xffff, 0x46fa, 20}, + {m68k_op_move_16_tos_pcix , 0xffff, 0x46fb, 22}, + {m68k_op_move_16_tos_i , 0xffff, 0x46fc, 16}, + {m68k_op_nbcd_8_pi7 , 0xffff, 0x481f, 12}, + {m68k_op_nbcd_8_pd7 , 0xffff, 0x4827, 14}, + {m68k_op_nbcd_8_aw , 0xffff, 0x4838, 16}, + {m68k_op_nbcd_8_al , 0xffff, 0x4839, 20}, + {m68k_op_pea_32_aw , 0xffff, 0x4878, 16}, + {m68k_op_pea_32_al , 0xffff, 0x4879, 20}, + {m68k_op_pea_32_pcdi , 0xffff, 0x487a, 16}, + {m68k_op_pea_32_pcix , 0xffff, 0x487b, 20}, + {m68k_op_movem_16_re_aw , 0xffff, 0x48b8, 12}, + {m68k_op_movem_16_re_al , 0xffff, 0x48b9, 16}, + {m68k_op_movem_32_re_aw , 0xffff, 0x48f8, 12}, + {m68k_op_movem_32_re_al , 0xffff, 0x48f9, 16}, + {m68k_op_tst_8_pi7 , 0xffff, 0x4a1f, 8}, + {m68k_op_tst_8_pd7 , 0xffff, 0x4a27, 10}, + {m68k_op_tst_8_aw , 0xffff, 0x4a38, 12}, + {m68k_op_tst_8_al , 0xffff, 0x4a39, 16}, + {m68k_op_tst_16_aw , 0xffff, 0x4a78, 12}, + {m68k_op_tst_16_al , 0xffff, 0x4a79, 16}, + {m68k_op_tst_32_aw , 0xffff, 0x4ab8, 16}, + {m68k_op_tst_32_al , 0xffff, 0x4ab9, 20}, + {m68k_op_tas_8_pi7 , 0xffff, 0x4adf, 18}, + {m68k_op_tas_8_pd7 , 0xffff, 0x4ae7, 20}, + {m68k_op_tas_8_aw , 0xffff, 0x4af8, 22}, + {m68k_op_tas_8_al , 0xffff, 0x4af9, 26}, + {m68k_op_illegal , 0xffff, 0x4afc, 4}, + {m68k_op_movem_16_er_aw , 0xffff, 0x4cb8, 16}, + {m68k_op_movem_16_er_al , 0xffff, 0x4cb9, 20}, + {m68k_op_movem_16_er_pcdi , 0xffff, 0x4cba, 16}, + {m68k_op_movem_16_er_pcix , 0xffff, 0x4cbb, 18}, + {m68k_op_movem_32_er_aw , 0xffff, 0x4cf8, 16}, + {m68k_op_movem_32_er_al , 0xffff, 0x4cf9, 20}, + {m68k_op_movem_32_er_pcdi , 0xffff, 0x4cfa, 16}, + {m68k_op_movem_32_er_pcix , 0xffff, 0x4cfb, 18}, + {m68k_op_link_16_a7 , 0xffff, 0x4e57, 16}, + {m68k_op_unlk_32_a7 , 0xffff, 0x4e5f, 12}, + {m68k_op_reset , 0xffff, 0x4e70, 0}, + {m68k_op_nop , 0xffff, 0x4e71, 4}, + {m68k_op_stop , 0xffff, 0x4e72, 4}, + {m68k_op_rte_32 , 0xffff, 0x4e73, 20}, + {m68k_op_rts_32 , 0xffff, 0x4e75, 16}, + {m68k_op_trapv , 0xffff, 0x4e76, 4}, + {m68k_op_rtr_32 , 0xffff, 0x4e77, 20}, + {m68k_op_jsr_32_aw , 0xffff, 0x4eb8, 18}, + {m68k_op_jsr_32_al , 0xffff, 0x4eb9, 20}, + {m68k_op_jsr_32_pcdi , 0xffff, 0x4eba, 18}, + {m68k_op_jsr_32_pcix , 0xffff, 0x4ebb, 22}, + {m68k_op_jmp_32_aw , 0xffff, 0x4ef8, 10}, + {m68k_op_jmp_32_al , 0xffff, 0x4ef9, 12}, + {m68k_op_jmp_32_pcdi , 0xffff, 0x4efa, 10}, + {m68k_op_jmp_32_pcix , 0xffff, 0x4efb, 14}, + {m68k_op_st_8_pi7 , 0xffff, 0x50df, 12}, + {m68k_op_st_8_pd7 , 0xffff, 0x50e7, 14}, + {m68k_op_st_8_aw , 0xffff, 0x50f8, 16}, + {m68k_op_st_8_al , 0xffff, 0x50f9, 20}, + {m68k_op_sf_8_pi7 , 0xffff, 0x51df, 12}, + {m68k_op_sf_8_pd7 , 0xffff, 0x51e7, 14}, + {m68k_op_sf_8_aw , 0xffff, 0x51f8, 16}, + {m68k_op_sf_8_al , 0xffff, 0x51f9, 20}, + {m68k_op_shi_8_pi7 , 0xffff, 0x52df, 12}, + {m68k_op_shi_8_pd7 , 0xffff, 0x52e7, 14}, + {m68k_op_shi_8_aw , 0xffff, 0x52f8, 16}, + {m68k_op_shi_8_al , 0xffff, 0x52f9, 20}, + {m68k_op_sls_8_pi7 , 0xffff, 0x53df, 12}, + {m68k_op_sls_8_pd7 , 0xffff, 0x53e7, 14}, + {m68k_op_sls_8_aw , 0xffff, 0x53f8, 16}, + {m68k_op_sls_8_al , 0xffff, 0x53f9, 20}, + {m68k_op_scc_8_pi7 , 0xffff, 0x54df, 12}, + {m68k_op_scc_8_pd7 , 0xffff, 0x54e7, 14}, + {m68k_op_scc_8_aw , 0xffff, 0x54f8, 16}, + {m68k_op_scc_8_al , 0xffff, 0x54f9, 20}, + {m68k_op_scs_8_pi7 , 0xffff, 0x55df, 12}, + {m68k_op_scs_8_pd7 , 0xffff, 0x55e7, 14}, + {m68k_op_scs_8_aw , 0xffff, 0x55f8, 16}, + {m68k_op_scs_8_al , 0xffff, 0x55f9, 20}, + {m68k_op_sne_8_pi7 , 0xffff, 0x56df, 12}, + {m68k_op_sne_8_pd7 , 0xffff, 0x56e7, 14}, + {m68k_op_sne_8_aw , 0xffff, 0x56f8, 16}, + {m68k_op_sne_8_al , 0xffff, 0x56f9, 20}, + {m68k_op_seq_8_pi7 , 0xffff, 0x57df, 12}, + {m68k_op_seq_8_pd7 , 0xffff, 0x57e7, 14}, + {m68k_op_seq_8_aw , 0xffff, 0x57f8, 16}, + {m68k_op_seq_8_al , 0xffff, 0x57f9, 20}, + {m68k_op_svc_8_pi7 , 0xffff, 0x58df, 12}, + {m68k_op_svc_8_pd7 , 0xffff, 0x58e7, 14}, + {m68k_op_svc_8_aw , 0xffff, 0x58f8, 16}, + {m68k_op_svc_8_al , 0xffff, 0x58f9, 20}, + {m68k_op_svs_8_pi7 , 0xffff, 0x59df, 12}, + {m68k_op_svs_8_pd7 , 0xffff, 0x59e7, 14}, + {m68k_op_svs_8_aw , 0xffff, 0x59f8, 16}, + {m68k_op_svs_8_al , 0xffff, 0x59f9, 20}, + {m68k_op_spl_8_pi7 , 0xffff, 0x5adf, 12}, + {m68k_op_spl_8_pd7 , 0xffff, 0x5ae7, 14}, + {m68k_op_spl_8_aw , 0xffff, 0x5af8, 16}, + {m68k_op_spl_8_al , 0xffff, 0x5af9, 20}, + {m68k_op_smi_8_pi7 , 0xffff, 0x5bdf, 12}, + {m68k_op_smi_8_pd7 , 0xffff, 0x5be7, 14}, + {m68k_op_smi_8_aw , 0xffff, 0x5bf8, 16}, + {m68k_op_smi_8_al , 0xffff, 0x5bf9, 20}, + {m68k_op_sge_8_pi7 , 0xffff, 0x5cdf, 12}, + {m68k_op_sge_8_pd7 , 0xffff, 0x5ce7, 14}, + {m68k_op_sge_8_aw , 0xffff, 0x5cf8, 16}, + {m68k_op_sge_8_al , 0xffff, 0x5cf9, 20}, + {m68k_op_slt_8_pi7 , 0xffff, 0x5ddf, 12}, + {m68k_op_slt_8_pd7 , 0xffff, 0x5de7, 14}, + {m68k_op_slt_8_aw , 0xffff, 0x5df8, 16}, + {m68k_op_slt_8_al , 0xffff, 0x5df9, 20}, + {m68k_op_sgt_8_pi7 , 0xffff, 0x5edf, 12}, + {m68k_op_sgt_8_pd7 , 0xffff, 0x5ee7, 14}, + {m68k_op_sgt_8_aw , 0xffff, 0x5ef8, 16}, + {m68k_op_sgt_8_al , 0xffff, 0x5ef9, 20}, + {m68k_op_sle_8_pi7 , 0xffff, 0x5fdf, 12}, + {m68k_op_sle_8_pd7 , 0xffff, 0x5fe7, 14}, + {m68k_op_sle_8_aw , 0xffff, 0x5ff8, 16}, + {m68k_op_sle_8_al , 0xffff, 0x5ff9, 20}, + {m68k_op_bra_16 , 0xffff, 0x6000, 10}, + {m68k_op_bra_32 , 0xffff, 0x60ff, 10}, + {m68k_op_bsr_16 , 0xffff, 0x6100, 18}, + {m68k_op_bsr_32 , 0xffff, 0x61ff, 18}, + {m68k_op_bhi_16 , 0xffff, 0x6200, 10}, + {m68k_op_bhi_32 , 0xffff, 0x62ff, 10}, + {m68k_op_bls_16 , 0xffff, 0x6300, 10}, + {m68k_op_bls_32 , 0xffff, 0x63ff, 10}, + {m68k_op_bcc_16 , 0xffff, 0x6400, 10}, + {m68k_op_bcc_32 , 0xffff, 0x64ff, 10}, + {m68k_op_bcs_16 , 0xffff, 0x6500, 10}, + {m68k_op_bcs_32 , 0xffff, 0x65ff, 10}, + {m68k_op_bne_16 , 0xffff, 0x6600, 10}, + {m68k_op_bne_32 , 0xffff, 0x66ff, 10}, + {m68k_op_beq_16 , 0xffff, 0x6700, 10}, + {m68k_op_beq_32 , 0xffff, 0x67ff, 10}, + {m68k_op_bvc_16 , 0xffff, 0x6800, 10}, + {m68k_op_bvc_32 , 0xffff, 0x68ff, 10}, + {m68k_op_bvs_16 , 0xffff, 0x6900, 10}, + {m68k_op_bvs_32 , 0xffff, 0x69ff, 10}, + {m68k_op_bpl_16 , 0xffff, 0x6a00, 10}, + {m68k_op_bpl_32 , 0xffff, 0x6aff, 10}, + {m68k_op_bmi_16 , 0xffff, 0x6b00, 10}, + {m68k_op_bmi_32 , 0xffff, 0x6bff, 10}, + {m68k_op_bge_16 , 0xffff, 0x6c00, 10}, + {m68k_op_bge_32 , 0xffff, 0x6cff, 10}, + {m68k_op_blt_16 , 0xffff, 0x6d00, 10}, + {m68k_op_blt_32 , 0xffff, 0x6dff, 10}, + {m68k_op_bgt_16 , 0xffff, 0x6e00, 10}, + {m68k_op_bgt_32 , 0xffff, 0x6eff, 10}, + {m68k_op_ble_16 , 0xffff, 0x6f00, 10}, + {m68k_op_ble_32 , 0xffff, 0x6fff, 10}, + {m68k_op_sbcd_8_mm_axy7 , 0xffff, 0x8f0f, 18}, + {m68k_op_subx_8_mm_axy7 , 0xffff, 0x9f0f, 18}, + {m68k_op_cmpm_8_axy7 , 0xffff, 0xbf0f, 12}, + {m68k_op_abcd_8_mm_axy7 , 0xffff, 0xcf0f, 18}, + {m68k_op_addx_8_mm_axy7 , 0xffff, 0xdf0f, 18}, + {m68k_op_asr_16_aw , 0xffff, 0xe0f8, 16}, + {m68k_op_asr_16_al , 0xffff, 0xe0f9, 20}, + {m68k_op_asl_16_aw , 0xffff, 0xe1f8, 16}, + {m68k_op_asl_16_al , 0xffff, 0xe1f9, 20}, + {m68k_op_lsr_16_aw , 0xffff, 0xe2f8, 16}, + {m68k_op_lsr_16_al , 0xffff, 0xe2f9, 20}, + {m68k_op_lsl_16_aw , 0xffff, 0xe3f8, 16}, + {m68k_op_lsl_16_al , 0xffff, 0xe3f9, 20}, + {m68k_op_roxr_16_aw , 0xffff, 0xe4f8, 16}, + {m68k_op_roxr_16_al , 0xffff, 0xe4f9, 20}, + {m68k_op_roxl_16_aw , 0xffff, 0xe5f8, 16}, + {m68k_op_roxl_16_al , 0xffff, 0xe5f9, 20}, + {m68k_op_ror_16_aw , 0xffff, 0xe6f8, 16}, + {m68k_op_ror_16_al , 0xffff, 0xe6f9, 20}, + {m68k_op_rol_16_aw , 0xffff, 0xe7f8, 16}, + {m68k_op_rol_16_al , 0xffff, 0xe7f9, 20}, + {0, 0, 0, 0} +}; + + +/* Build the opcode handler jump table */ +static void m68ki_build_opcode_table(void) +{ + const opcode_handler_struct *ostruct; + int instr; + int i; + int j; + + for(i = 0; i < 0x10000; i++) + { + /* default to illegal */ + m68ki_instruction_jump_table[i] = m68k_op_illegal; + m68ki_cycles[i] = 4; + } + + ostruct = &m68k_opcode_handler_table[0]; + while(ostruct->mask != 0xff00) + { + for(i = 0;i < 0x10000;i++) + { + if((i & ostruct->mask) == ostruct->match) + { + m68ki_instruction_jump_table[i] = ostruct->opcode_handler; + m68ki_cycles[i] = ostruct->cycles * MUL; + } + } + ostruct++; + } + while(ostruct->mask == 0xff00) + { + for(i = 0;i <= 0xff;i++) + { + m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler; + m68ki_cycles[ostruct->match | i] = ostruct->cycles * MUL; + } + ostruct++; + } + while(ostruct->mask == 0xf1f8) + { + for(i = 0;i < 8;i++) + { + for(j = 0;j < 8;j++) + { + instr = ostruct->match | (i << 9) | j; + m68ki_instruction_jump_table[instr] = ostruct->opcode_handler; + m68ki_cycles[instr] = ostruct->cycles * MUL; + } + } + ostruct++; + } + while(ostruct->mask == 0xfff0) + { + for(i = 0;i <= 0x0f;i++) + { + m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler; + m68ki_cycles[ostruct->match | i] = ostruct->cycles * MUL; + } + ostruct++; + } + while(ostruct->mask == 0xf1ff) + { + for(i = 0;i <= 0x07;i++) + { + m68ki_instruction_jump_table[ostruct->match | (i << 9)] = ostruct->opcode_handler; + m68ki_cycles[ostruct->match | (i << 9)] = ostruct->cycles * MUL; + } + ostruct++; + } + while(ostruct->mask == 0xfff8) + { + for(i = 0;i <= 0x07;i++) + { + m68ki_instruction_jump_table[ostruct->match | i] = ostruct->opcode_handler; + m68ki_cycles[ostruct->match | i] = ostruct->cycles * MUL; + } + ostruct++; + } + while(ostruct->mask == 0xffff) + { + m68ki_instruction_jump_table[ostruct->match] = ostruct->opcode_handler; + m68ki_cycles[ostruct->match] = ostruct->cycles * MUL; + ostruct++; + } +} + +#endif + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + + diff --git a/genplus-gx/core/m68k/readme.txt b/genplus-gx/core/m68k/readme.txt new file mode 100644 index 0000000000..48e603faae --- /dev/null +++ b/genplus-gx/core/m68k/readme.txt @@ -0,0 +1,315 @@ + MUSASHI + ======= + + Version 3.3 + + A portable Motorola M680x0 processor emulation engine. + Copyright 1998-2001 Karl Stenerud. All rights reserved. + + + +INTRODUCTION: +------------ + +Musashi is a Motorola 68000, 68010, 68EC020, and 68020 emulator written in C. +This emulator was written with two goals in mind: portability and speed. + +The emulator is written to ANSI C specifications with the exception that I use +inline functions. This is not compliant to the ANSI spec, but will be +compliant to the ANSI C9X spec. + +It has been successfully running in the MAME project (www.mame.net) for over 2 +years and so has had time to mature. + + + +LICENSE AND COPYRIGHT: +--------------------- + +The Musashi M680x0 emulator is copyright 1998-2001 Karl Stenerud. + +The source code included in this archive is provided AS-IS, free for any +non-commercial purpose. + +If you build a program using this core, please give credit to the author. + +If you wish to use this core in a commercial environment, please contact +the author to discuss commercial licensing. + + + +AVAILABILITY: +------------ +The latest version of this code can be obtained at: +http://kstenerud.cjb.net + + + +CONTACTING THE AUTHOR: +--------------------- +I can be reached at kstenerud@mame.net + + + +BASIC CONFIGURATION: +------------------- +The basic configuration will give you a standard 68000 that has sufficient +functionality to work in a primitive environment. + +This setup assumes that you only have 1 device interrupting it, that the +device will always request an autovectored interrupt, and it will always clear +the interrupt before the interrupt service routine finishes (but could +possibly re-assert the interrupt). +You will have only one address space, no tracing, and no instruction prefetch. + +To implement the basic configuration: + +- Open m68kconf.h and verify that the settings for INLINE and DECL_SPEC will + work with your compiler. (They are set for gcc) + +- In your host program, implement the following functions: + unsigned int m68k_read_memory_8(unsigned int address); + unsigned int m68k_read_memory_16(unsigned int address); + unsigned int m68k_read_memory_32(unsigned int address); + void m68k_write_memory_8(unsigned int address, unsigned int value); + void m68k_write_memory_16(unsigned int address, unsigned int value); + void m68k_write_memory_32(unsigned int address, unsigned int value); + +- In your host program, be sure to call m68k_pulse_reset() once before calling + any of the other functions as this initializes the core. + +- Use m68k_execute() to execute instructions and m68k_set_irq() to cause an + interrupt. + + + +ADDING PROPER INTERRUPT HANDLING: +-------------------------------- +The interrupt handling in the basic configuration doesn't emulate the +interrupt acknowledge phase of the CPU and automatically clears an interrupt +request during interrupt processing. +While this works for most systems, you may need more accurate interrupt +handling. + +To add proper interrupt handling: + +- In m68kconf.h, set M68K_EMULATE_INT_ACK to OPT_SPECIFY_HANDLER + +- In m68kconf.h, set M68K_INT_ACK_CALLBACK(A) to your interrupt acknowledge + routine + +- Your interrupt acknowledge routine must return an interrupt vector, + M68K_INT_ACK_AUTOVECTOR, or M68K_INT_ACK_SPURIOUS. most m68k + implementations just use autovectored interrupts. + +- When the interrupting device is satisfied, you must call m68k_set_irq(0) to + remove the interrupt request. + + + +MULTIPLE INTERRUPTS: +------------------- +The above system will work if you have only one device interrupting the CPU, +but if you have more than one device, you must do a bit more. + +To add multiple interrupts: + +- You must make an interrupt arbitration device that will take the highest + priority interrupt and encode it onto the IRQ pins on the CPU. + +- The interrupt arbitration device should use m68k_set_irq() to set the + highest pending interrupt, or 0 for no interrupts pending. + + + +SEPARATE IMMEDIATE AND PC-RELATIVE READS: +---------------------------------------- +You can write faster memory access functions if you know whether you are +fetching from ROM or RAM. Immediate reads are always from the program space +(Always in ROM unless it is running self-modifying code). +This will also separate the pc-relative reads, since some systems treat +PROGRAM mode reads and DATA mode reads differently (for program encryption, +for instance). See the section below (ADDRESS SPACE) for an explanation of +PROGRAM and DATA mode. + +To enable separate reads: + +- In m68kconf.h, turn on M68K_SEPARATE_READS. + +- In your host program, implement the following functions: + unsigned int m68k_read_immediate_16(unsigned int address); + unsigned int m68k_read_immediate_32(unsigned int address); + + unsigned int m68k_read_pcrelative_8(unsigned int address); + unsigned int m68k_read_pcrelative_16(unsigned int address); + unsigned int m68k_read_pcrelative_32(unsigned int address); + +- If you need to know the current PC (for banking and such), set + M68K_MONITOR_PC to OPT_SPECIFY_HANDLER, and set M68K_SET_PC_CALLBACK(A) to + your routine. + + + +ADDRESS SPACES: +-------------- +Most systems will only implement one address space, placing ROM at the lower +addresses and RAM at the higher. However, there is the possibility that a +system will implement ROM and RAM in the same address range, but in different +address spaces, or will have different mamory types that require different +handling for the program and the data. + +The 68k accomodates this by allowing different program spaces, the most +important to us being PROGRAM and DATA space. Here is a breakdown of +how information is fetched: + +- All immediate reads are fetched from PROGRAM space. + +- All PC-relative reads are fetched from PROGRAM space. + +- The initial stack pointer and program counter are fetched from PROGRAM space. + +- All other reads (except for those from the moves instruction for 68020) + are fetched from DATA space. + +The m68k deals with this by encoding the requested address space on the +function code pins: + + FC + Address Space 210 + ------------------ --- + USER DATA 001 + USER PROGRAM 010 + SUPERVISOR DATA 101 + SUPERVISOR PROGRAM 110 + CPU SPACE 111 <-- not emulated in this core since we emulate + interrupt acknowledge in another way. + +Problems arise here if you need to emulate this distinction (if, for example, +your ROM and RAM are at the same address range, with RAM and ROM enable +wired to the function code pins). + +There are 2 ways to deal with this situation using Musashi: + +1. If you only need the distinction between PROGRAM and DATA (the most common), + you can just separate the reads (see the preceeding section). This is the + faster solution. + +2. You can emulate the function code pins entirely. + +To emulate the function code pins: + +- In m68kconf.h, set M68K_EMULATE_FC to OPT_SPECIFY_HANDLER and set + M68K_SET_FC_CALLBACK(A) to your function code handler function. + +- Your function code handler should select the proper address space for + subsequent calls to m68k_read_xx (and m68k_write_xx for 68010+). + +Note: immediate reads are always done from program space, so technically you + don't need to implement the separate immediate reads, although you could + gain more speed improvements leaving them in and doing some clever + programming. + + + +USING DIFFERENT CPU TYPES: +------------------------- +The default is to enable only the 68000 cpu type. To change this, change the +settings for M68K_EMULATE_010 etc in m68kconf.h. + +To set the CPU type you want to use: + +- Make sure it is enabled in m68kconf.h. Current switches are: + M68K_EMULATE_010 + M68K_EMULATE_EC020 + M68K_EMULATE_020 + +- In your host program, call m68k_set_cpu_type() and then call + m68k_pulse_reset(). Valid CPU types are: + M68K_CPU_TYPE_68000, + M68K_CPU_TYPE_68010, + M68K_CPU_TYPE_68EC020, + M68K_CPU_TYPE_68020 + + + +CLOCK FREQUENCY: +--------------- +In order to emulate the correct clock frequency, you will have to calculate +how long it takes the emulation to execute a certain number of "cycles" and +vary your calls to m68k_execute() accordingly. +As well, it is a good idea to take away the CPU's timeslice when it writes to +a memory-mapped port in order to give the device it wrote to a chance to +react. + +You can use the functions m68k_cycles_run(), m68k_cycles_remaining(), +m68k_modify_timeslice(), and m68k_end_timeslice() to do this. +Try to use large cycle values in your calls to m68k_execute() since it will +increase throughput. You can always take away the timeslice later. + + + +MORE CORRECT EMULATION: +---------------------- +You may need to enable these in order to properly emulate some of the more +obscure functions of the m68k: + +- M68K_EMULATE_BKPT_ACK causes the CPU to call a breakpoint handler on a BKPT + instruction + +- M68K_EMULATE_TRACE causes the CPU to generate trace exceptions when the + trace bits are set + +- M68K_EMULATE_RESET causes the CPU to call a reset handler on a RESET + instruction. + +- M68K_EMULATE_PREFETCH emulates the 4-word instruction prefetch that is part + of the 68000/68010 (needed for Amiga emulation). + +- call m68k_pulse_halt() to emulate the HALT pin. + + + +CONVENIENCE FUNCTIONS: +--------------------- +These are in here for programmer convenience: + +- M68K_INSTRUCTION_HOOK lets you call a handler before each instruction. + +- M68K_LOG_ENABLE and M68K_LOG_1010_1111 lets you log illegal and A/F-line + instructions. + + + +MULTIPLE CPU EMULATION: +---------------------- +The default is to use only one CPU. To use more than one CPU in this core, +there are some things to keep in mind: + +- To have different cpus call different functions, use OPT_ON instead of + OPT_SPECIFY_HANDLER, and use the m68k_set_xxx_callback() functions to set + your callback handlers on a per-cpu basis. + +- Be sure to call set_cpu_type() for each CPU you use. + +- Use m68k_set_context() and m68k_get_context() to switch to another CPU. + + + +LOAD AND SAVE CPU CONTEXTS FROM DISK: +------------------------------------ +You can use them68k_load_context() and m68k_save_context() functions to load +and save the CPU state to disk. + + + +GET/SET INFORMATION FROM THE CPU: +-------------------------------- +You can use m68k_get_reg() and m68k_set_reg() to gain access to the internals +of the CPU. + + + +EXAMPLE: +------- + +I have included a file example.zip that contains a full example. diff --git a/genplus-gx/core/m68k/s68kconf.h b/genplus-gx/core/m68k/s68kconf.h new file mode 100644 index 0000000000..07431fbd2f --- /dev/null +++ b/genplus-gx/core/m68k/s68kconf.h @@ -0,0 +1,93 @@ +#ifndef M68KCONF__HEADER +#define M68KCONF__HEADER + +/* ======================================================================== */ +/* ======================== SUB 68K CONFIGURATION ========================= */ +/* ======================================================================== */ + +/* Configuration switches. + * Use OPT_SPECIFY_HANDLER for configuration options that allow callbacks. + * OPT_SPECIFY_HANDLER causes the core to link directly to the function + * or macro you specify, rather than using callback functions whose pointer + * must be passed in using m68k_set_xxx_callback(). + */ +#define OPT_OFF 0 +#define OPT_ON 1 +#define OPT_SPECIFY_HANDLER 2 + +/* If ON, the CPU will call m68k_write_32_pd() when it executes move.l with a + * predecrement destination EA mode instead of m68k_write_32(). + * To simulate real 68k behavior, m68k_write_32_pd() must first write the high + * word to [address+2], and then write the low word to [address]. + */ +#define M68K_SIMULATE_PD_WRITES OPT_OFF + +/* If ON, CPU will call the interrupt acknowledge callback when it services an + * interrupt. + * If off, all interrupts will be autovectored and all interrupt requests will + * auto-clear when the interrupt is serviced. + */ +#define M68K_EMULATE_INT_ACK OPT_SPECIFY_HANDLER +#define M68K_INT_ACK_CALLBACK(A) scd_68k_irq_ack(A) + +/* If ON, CPU will call the output reset callback when it encounters a reset + * instruction. + */ +#define M68K_EMULATE_RESET OPT_OFF +#define M68K_RESET_CALLBACK() your_reset_handler_function() + +/* If ON, CPU will call the callback when it encounters a tas + * instruction. + */ +#define M68K_TAS_HAS_CALLBACK OPT_SPECIFY_HANDLER +#define M68K_TAS_CALLBACK() 1 + +/* If ON, CPU will call the set fc callback on every memory access to + * differentiate between user/supervisor, program/data access like a real + * 68000 would. This should be enabled and the callback should be set if you + * want to properly emulate the m68010 or higher. (moves uses function codes + * to read/write data from different address spaces) + */ +#define M68K_EMULATE_FC OPT_OFF +#define M68K_SET_FC_CALLBACK(A) your_set_fc_handler_function(A) + +/* If ON, the CPU will monitor the trace flags and take trace exceptions + */ +#define M68K_EMULATE_TRACE OPT_OFF + +/* If ON, the CPU will emulate the 4-byte prefetch queue of a real 68000 */ +#define M68K_EMULATE_PREFETCH OPT_OFF + +/* If ON, the CPU will generate address error exceptions if it tries to + * access a word or longword at an odd address. + * NOTE: This is only emulated properly for 68000 mode. + */ +#define M68K_EMULATE_ADDRESS_ERROR OPT_OFF + +/* If ON and previous option is also ON, address error exceptions will + also be checked when fetching instructions. Disabling this can help + speeding up emulation while still emulating address error exceptions + on other memory access if needed. + * NOTE: This is only emulated properly for 68000 mode. + */ +#define M68K_CHECK_PC_ADDRESS_ERROR OPT_OFF + + +/* ----------------------------- COMPATIBILITY ---------------------------- */ + +/* The following options set optimizations that violate the current ANSI + * standard, but will be compliant under the forthcoming C9X standard. + */ + + +/* If ON, the enulation core will use 64-bit integers to speed up some + * operations. +*/ +#define M68K_USE_64_BIT OPT_OFF + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + +#endif /* M68KCONF__HEADER */ diff --git a/genplus-gx/core/m68k/s68kcpu.c b/genplus-gx/core/m68k/s68kcpu.c new file mode 100644 index 0000000000..452d48b2df --- /dev/null +++ b/genplus-gx/core/m68k/s68kcpu.c @@ -0,0 +1,349 @@ +/* ======================================================================== */ +/* SUB 68K CORE */ +/* ======================================================================== */ + +extern int scd_68k_irq_ack(int level); + +#define m68ki_cpu s68k +#define MUL (4) + +/* ======================================================================== */ +/* ================================ INCLUDES ============================== */ +/* ======================================================================== */ + +#ifndef BUILD_TABLES +#include "s68ki_cycles.h" +#endif + +#include "s68kconf.h" +#include "m68kcpu.h" +#include "m68kops.h" + +/* ======================================================================== */ +/* ================================= DATA ================================= */ +/* ======================================================================== */ + +#ifdef BUILD_TABLES +static unsigned char s68ki_cycles[0x10000]; +#endif +static int irq_latency; + +/* IRQ priority */ +static const uint8 irq_level[0x40] = +{ + 0, 1, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 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, 6, 6, 6, 6, 6 +}; + +m68ki_cpu_core s68k; + + +/* ======================================================================== */ +/* =============================== CALLBACKS ============================== */ +/* ======================================================================== */ + +/* Default callbacks used if the callback hasn't been set yet, or if the + * callback is set to NULL + */ + +#if M68K_EMULATE_INT_ACK == OPT_ON +/* Interrupt acknowledge */ +static int default_int_ack_callback(int int_level) +{ + CPU_INT_LEVEL = 0; + return M68K_INT_ACK_AUTOVECTOR; +} +#endif + +#if M68K_EMULATE_RESET == OPT_ON +/* Called when a reset instruction is executed */ +static void default_reset_instr_callback(void) +{ +} +#endif + +#if M68K_TAS_HAS_CALLBACK == OPT_ON +/* Called when a tas instruction is executed */ +static int default_tas_instr_callback(void) +{ + return 1; // allow writeback +} +#endif + +#if M68K_EMULATE_FC == OPT_ON +/* Called every time there's bus activity (read/write to/from memory */ +static void default_set_fc_callback(unsigned int new_fc) +{ +} +#endif + + +/* ======================================================================== */ +/* ================================= API ================================== */ +/* ======================================================================== */ + +/* Access the internals of the CPU */ +unsigned int s68k_get_reg(m68k_register_t regnum) +{ + switch(regnum) + { + case M68K_REG_D0: return m68ki_cpu.dar[0]; + case M68K_REG_D1: return m68ki_cpu.dar[1]; + case M68K_REG_D2: return m68ki_cpu.dar[2]; + case M68K_REG_D3: return m68ki_cpu.dar[3]; + case M68K_REG_D4: return m68ki_cpu.dar[4]; + case M68K_REG_D5: return m68ki_cpu.dar[5]; + case M68K_REG_D6: return m68ki_cpu.dar[6]; + case M68K_REG_D7: return m68ki_cpu.dar[7]; + case M68K_REG_A0: return m68ki_cpu.dar[8]; + case M68K_REG_A1: return m68ki_cpu.dar[9]; + case M68K_REG_A2: return m68ki_cpu.dar[10]; + case M68K_REG_A3: return m68ki_cpu.dar[11]; + case M68K_REG_A4: return m68ki_cpu.dar[12]; + case M68K_REG_A5: return m68ki_cpu.dar[13]; + case M68K_REG_A6: return m68ki_cpu.dar[14]; + case M68K_REG_A7: return m68ki_cpu.dar[15]; + case M68K_REG_PC: return MASK_OUT_ABOVE_32(m68ki_cpu.pc); + case M68K_REG_SR: return m68ki_cpu.t1_flag | + (m68ki_cpu.s_flag << 11) | + m68ki_cpu.int_mask | + ((m68ki_cpu.x_flag & XFLAG_SET) >> 4) | + ((m68ki_cpu.n_flag & NFLAG_SET) >> 4) | + ((!m68ki_cpu.not_z_flag) << 2) | + ((m68ki_cpu.v_flag & VFLAG_SET) >> 6) | + ((m68ki_cpu.c_flag & CFLAG_SET) >> 8); + case M68K_REG_SP: return m68ki_cpu.dar[15]; + case M68K_REG_USP: return m68ki_cpu.s_flag ? m68ki_cpu.sp[0] : m68ki_cpu.dar[15]; + case M68K_REG_ISP: return m68ki_cpu.s_flag ? m68ki_cpu.dar[15] : m68ki_cpu.sp[4]; +#if M68K_EMULATE_PREFETCH + case M68K_REG_PREF_ADDR: return m68ki_cpu.pref_addr; + case M68K_REG_PREF_DATA: return m68ki_cpu.pref_data; +#endif + case M68K_REG_IR: return m68ki_cpu.ir; + default: return 0; + } +} + +void s68k_set_reg(m68k_register_t regnum, unsigned int value) +{ + switch(regnum) + { + case M68K_REG_D0: REG_D[0] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D1: REG_D[1] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D2: REG_D[2] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D3: REG_D[3] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D4: REG_D[4] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D5: REG_D[5] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D6: REG_D[6] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_D7: REG_D[7] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A0: REG_A[0] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A1: REG_A[1] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A2: REG_A[2] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A3: REG_A[3] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A4: REG_A[4] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A5: REG_A[5] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A6: REG_A[6] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_A7: REG_A[7] = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_PC: m68ki_jump(MASK_OUT_ABOVE_32(value)); return; + case M68K_REG_SR: m68ki_set_sr(value); return; + case M68K_REG_SP: REG_SP = MASK_OUT_ABOVE_32(value); return; + case M68K_REG_USP: if(FLAG_S) + REG_USP = MASK_OUT_ABOVE_32(value); + else + REG_SP = MASK_OUT_ABOVE_32(value); + return; + case M68K_REG_ISP: if(FLAG_S) + REG_SP = MASK_OUT_ABOVE_32(value); + else + REG_ISP = MASK_OUT_ABOVE_32(value); + return; + case M68K_REG_IR: REG_IR = MASK_OUT_ABOVE_16(value); return; +#if M68K_EMULATE_PREFETCH + case M68K_REG_PREF_ADDR: CPU_PREF_ADDR = MASK_OUT_ABOVE_32(value); return; +#endif + default: return; + } +} + +/* Set the callbacks */ +#if M68K_EMULATE_INT_ACK == OPT_ON +void s68k_set_int_ack_callback(int (*callback)(int int_level)) +{ + CALLBACK_INT_ACK = callback ? callback : default_int_ack_callback; +} +#endif + +#if M68K_EMULATE_RESET == OPT_ON +void s68k_set_reset_instr_callback(void (*callback)(void)) +{ + CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback; +} +#endif + +#if M68K_TAS_HAS_CALLBACK == OPT_ON +void s68k_set_tas_instr_callback(int (*callback)(void)) +{ + CALLBACK_TAS_INSTR = callback ? callback : default_tas_instr_callback; +} +#endif + +#if M68K_EMULATE_FC == OPT_ON +void s68k_set_fc_callback(void (*callback)(unsigned int new_fc)) +{ + CALLBACK_SET_FC = callback ? callback : default_set_fc_callback; +} +#endif + +extern void error(char *format, ...); +extern uint16 v_counter; + +/* update IRQ level according to triggered interrupts */ +void s68k_update_irq(unsigned int mask) +{ + /* Get IRQ level (6 interrupt lines) */ + mask = irq_level[mask]; + + /* Set IRQ level */ + CPU_INT_LEVEL = mask << 8; + +#ifdef LOG_SCD + error("[%d][%d] IRQ Level = %d(0x%02x) (%x)\n", v_counter, s68k.cycles, CPU_INT_LEVEL>>8,FLAG_INT_MASK,s68k.pc); +#endif +} + +void s68k_run(unsigned int cycles) +{ + /* Make sure CPU is not already ahead */ + if (s68k.cycles >= cycles) + { + return; + } + + /* Check interrupt mask to process IRQ if needed */ + m68ki_check_interrupts(); + + /* Make sure we're not stopped */ + if (CPU_STOPPED) + { + s68k.cycles = cycles; + return; + } + + /* Save end cycles count for when CPU is stopped */ + s68k.cycle_end = cycles; + + /* Return point for when we have an address error (TODO: use goto) */ + m68ki_set_address_error_trap() /* auto-disable (see m68kcpu.h) */ + +#ifdef LOG_SCD + error("[%d][%d] s68k run to %d cycles (%x), irq mask = %x (%x)\n", v_counter, s68k.cycles, cycles, s68k.pc,FLAG_INT_MASK, CPU_INT_LEVEL); +#endif + + while (s68k.cycles < cycles) + { + /* Set tracing accodring to T1. */ + m68ki_trace_t1() /* auto-disable (see m68kcpu.h) */ + + /* Set the address space for reads */ + m68ki_use_data_space() /* auto-disable (see m68kcpu.h) */ + + /* Decode next instruction */ + REG_IR = m68ki_read_imm_16(); + + /* Execute instruction */ + m68ki_instruction_jump_table[REG_IR](); + USE_CYCLES(CYC_INSTRUCTION[REG_IR]); + + /* Trace m68k_exception, if necessary */ + m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */ + } +} + +void s68k_init(void) +{ +#ifdef BUILD_TABLES + static uint emulation_initialized = 0; + + /* The first call to this function initializes the opcode handler jump table */ + if(!emulation_initialized) + { + m68ki_build_opcode_table(); + emulation_initialized = 1; + } +#endif + +#if M68K_EMULATE_INT_ACK == OPT_ON + s68k_set_int_ack_callback(NULL); +#endif +#if M68K_EMULATE_RESET == OPT_ON + s68k_set_reset_instr_callback(NULL); +#endif +#if M68K_TAS_HAS_CALLBACK == OPT_ON + s68k_set_tas_instr_callback(NULL); +#endif +#if M68K_EMULATE_FC == OPT_ON + s68k_set_fc_callback(NULL); +#endif +} + +/* Pulse the RESET line on the CPU */ +void s68k_pulse_reset(void) +{ + /* Clear all stop levels */ + CPU_STOPPED = 0; +#if M68K_EMULATE_ADDRESS_ERROR + CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; +#endif + + /* Turn off tracing */ + FLAG_T1 = 0; + m68ki_clear_trace() + + /* Interrupt mask to level 7 */ + FLAG_INT_MASK = 0x0700; + CPU_INT_LEVEL = 0; + irq_latency = 0; + + /* Go to supervisor mode */ + m68ki_set_s_flag(SFLAG_SET); + + /* Invalidate the prefetch queue */ +#if M68K_EMULATE_PREFETCH + /* Set to arbitrary number since our first fetch is from 0 */ + CPU_PREF_ADDR = 0x1000; +#endif /* M68K_EMULATE_PREFETCH */ + + /* Read the initial stack pointer and program counter */ + m68ki_jump(0); + REG_SP = m68ki_read_imm_32(); + REG_PC = m68ki_read_imm_32(); + m68ki_jump(REG_PC); + +#if M68K_EMULATE_ADDRESS_ERROR + CPU_RUN_MODE = RUN_MODE_NORMAL; +#endif + + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_RESET]); +} + +void s68k_pulse_halt(void) +{ + /* Pulse the HALT line on the CPU */ + CPU_STOPPED |= STOP_LEVEL_HALT; +} + +void s68k_clear_halt() +{ + /* Clear the HALT line on the CPU */ + CPU_STOPPED &= ~STOP_LEVEL_HALT; +} + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ diff --git a/genplus-gx/core/m68k/s68ki_cycles.h b/genplus-gx/core/m68k/s68ki_cycles.h new file mode 100644 index 0000000000..bbadeda5fa --- /dev/null +++ b/genplus-gx/core/m68k/s68ki_cycles.h @@ -0,0 +1,4099 @@ +static const unsigned char m68ki_cycles[0x10000] = +{ + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 20*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 20*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, + 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 32*4, 36*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 20*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 20*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, + 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 32*4, 36*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, + 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 32*4, 36*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, + 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 32*4, 36*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 20*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 0*4, 0*4, 20*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, + 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 32*4, 36*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 28*4, 32*4, 28*4, 30*4, 24*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 30*4, 34*4, 30*4, 32*4, 26*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 28*4, 32*4, 28*4, 30*4, 24*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 28*4, 32*4, 28*4, 30*4, 24*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 30*4, 34*4, 30*4, 32*4, 26*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, + 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 34*4, 32*4, 36*4, 32*4, 34*4, 28*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 28*4, 32*4, 28*4, 30*4, 24*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 30*4, 34*4, 30*4, 32*4, 26*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 28*4, 32*4, 28*4, 30*4, 24*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 30*4, 34*4, 30*4, 32*4, 26*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 28*4, 32*4, 28*4, 30*4, 24*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 30*4, 34*4, 30*4, 32*4, 26*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 28*4, 32*4, 28*4, 30*4, 24*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 30*4, 34*4, 30*4, 32*4, 26*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 28*4, 32*4, 28*4, 30*4, 24*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 30*4, 34*4, 30*4, 32*4, 26*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, + 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 28*4, 32*4, 28*4, 30*4, 24*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, + 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 28*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 32*4, 30*4, 34*4, 30*4, 32*4, 26*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 24*4, 26*4, 20*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 22*4, 24*4, 18*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 8*4, 12*4, 8*4, 12*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 8*4, 12*4, 8*4, 12*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 8*4, 12*4, 8*4, 12*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 20*4, 24*4, 20*4, 22*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 8*4, 12*4, 8*4, 12*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 16*4, 20*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 8*4, 12*4, 8*4, 12*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, + 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 22*4, 26*4, 0*4, 0*4, 4*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 8*4, 12*4, 8*4, 12*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 8*4, 12*4, 8*4, 12*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*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, 4*4, 4*4, 4*4, + 0*4, 4*4, 4*4, 20*4, 0*4, 16*4, 4*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 18*4, 20*4, 18*4, 22*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 10*4, 12*4, 10*4, 14*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 8*4, 12*4, 8*4, 12*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 14*4, 18*4, 14*4, 16*4, 10*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 14*4, 18*4, 14*4, 16*4, 10*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 14*4, 18*4, 14*4, 16*4, 10*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 14*4, 18*4, 14*4, 16*4, 10*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 14*4, 18*4, 14*4, 16*4, 10*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 14*4, 18*4, 14*4, 16*4, 10*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 14*4, 18*4, 14*4, 16*4, 10*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 14*4, 18*4, 14*4, 16*4, 10*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 14*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 8*4, 12*4, 8*4, 10*4, 4*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*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, 4*4, 4*4, 4*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 10*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 12*4, 16*4, 12*4, 14*4, 8*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 16*4, 18*4, 12*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, 30*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, + 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 22*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, 24*4, + 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 26*4, 24*4, 28*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, + 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, + 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 20*4, 18*4, 22*4, 18*4, 20*4, 16*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, 12*4, + 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 14*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, 16*4, + 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 18*4, 16*4, 20*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, 6*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, 8*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, + 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*4, 0*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, + 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 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*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, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, +}; diff --git a/genplus-gx/core/macros.h b/genplus-gx/core/macros.h new file mode 100644 index 0000000000..6e5f4f7d56 --- /dev/null +++ b/genplus-gx/core/macros.h @@ -0,0 +1,49 @@ +#ifndef _MACROS_H_ +#define _MACROS_H_ + +#ifdef LSB_FIRST + +#define READ_BYTE(BASE, ADDR) (BASE)[(ADDR)^1] + +#define READ_WORD(BASE, ADDR) (((BASE)[ADDR]<<8) | (BASE)[(ADDR)+1]) + +#define READ_WORD_LONG(BASE, ADDR) (((BASE)[(ADDR)+1]<<24) | \ + ((BASE)[(ADDR)]<<16) | \ + ((BASE)[(ADDR)+3]<<8) | \ + (BASE)[(ADDR)+2]) + +#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[(ADDR)^1] = (VAL)&0xff + +#define WRITE_WORD(BASE, ADDR, VAL) (BASE)[ADDR] = ((VAL)>>8) & 0xff; \ + (BASE)[(ADDR)+1] = (VAL)&0xff + +#define WRITE_WORD_LONG(BASE, ADDR, VAL) (BASE)[(ADDR+1)] = ((VAL)>>24) & 0xff; \ + (BASE)[(ADDR)] = ((VAL)>>16)&0xff; \ + (BASE)[(ADDR+3)] = ((VAL)>>8)&0xff; \ + (BASE)[(ADDR+2)] = (VAL)&0xff + +#else + +#define READ_BYTE(BASE, ADDR) (BASE)[ADDR] +#define READ_WORD(BASE, ADDR) *(uint16 *)((BASE) + (ADDR)) +#define READ_WORD_LONG(BASE, ADDR) *(uint32 *)((BASE) + (ADDR)) +#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[ADDR] = VAL & 0xff +#define WRITE_WORD(BASE, ADDR, VAL) *(uint16 *)((BASE) + (ADDR)) = VAL & 0xffff +#define WRITE_WORD_LONG(BASE, ADDR, VAL) *(uint32 *)((BASE) + (ADDR)) = VAL & 0xffffffff +#endif + +/* C89 compatibility */ +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327f +#endif /* M_PI */ + +/* Set to your compiler's static inline keyword to enable it, or + * set it to blank to disable it. + * If you define INLINE in the makefile, it will override this value. + * NOTE: not enabling inline functions will SEVERELY slow down emulation. + */ +#ifndef INLINE +#define INLINE static __inline__ +#endif /* INLINE */ + +#endif /* _MACROS_H_ */ diff --git a/genplus-gx/core/mem68k.c b/genplus-gx/core/mem68k.c new file mode 100644 index 0000000000..78f2d82009 --- /dev/null +++ b/genplus-gx/core/mem68k.c @@ -0,0 +1,1281 @@ +/*************************************************************************************** + * Genesis Plus + * Main 68k bus handlers + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +/*--------------------------------------------------------------------------*/ +/* Unused areas (return open bus data, i.e prefetched instruction word) */ +/*--------------------------------------------------------------------------*/ + +unsigned int m68k_read_bus_8(unsigned int address) +{ +#ifdef LOGERROR + error("Unused read8 %08X (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); +#endif + address = m68k.pc | (address & 1); + return READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff); +} + +unsigned int m68k_read_bus_16(unsigned int address) +{ +#ifdef LOGERROR + error("Unused read16 %08X (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); +#endif + address = m68k.pc; + return *(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)); +} + + +void m68k_unused_8_w(unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error("Unused write8 %08X = %02X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); +#endif +} + +void m68k_unused_16_w(unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error("Unused write16 %08X = %04X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); +#endif +} + + +/*--------------------------------------------------------------------------*/ +/* Illegal areas (cause system to lock-up since !DTACK is not returned) */ +/*--------------------------------------------------------------------------*/ + +void m68k_lockup_w_8 (unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error ("Lockup %08X = %02X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); +#endif + if (!config.force_dtack) + { + m68k_pulse_halt(); + m68k.cycles = m68k.cycle_end; + } +} + +void m68k_lockup_w_16 (unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error ("Lockup %08X = %04X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); +#endif + if (!config.force_dtack) + { + m68k_pulse_halt(); + m68k.cycles = m68k.cycle_end; + } +} + +unsigned int m68k_lockup_r_8 (unsigned int address) +{ +#ifdef LOGERROR + error ("Lockup %08X.b (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); +#endif + if (!config.force_dtack) + { + m68k_pulse_halt(); + m68k.cycles = m68k.cycle_end; + } + address = m68k.pc | (address & 1); + return READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff); +} + +unsigned int m68k_lockup_r_16 (unsigned int address) +{ +#ifdef LOGERROR + error ("Lockup %08X.w (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); +#endif + if (!config.force_dtack) + { + m68k_pulse_halt(); + m68k.cycles = m68k.cycle_end; + } + address = m68k.pc; + return *(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)); +} + + +/*--------------------------------------------------------------------------*/ +/* Z80 bus (accessed through I/O chip) */ +/*--------------------------------------------------------------------------*/ + +unsigned int z80_read_byte(unsigned int address) +{ + switch ((address >> 13) & 3) + { + case 2: /* YM2612 */ + { + return fm_read(m68k.cycles, address & 3); + } + + case 3: /* Misc */ + { + /* VDP (through 68k bus) */ + if ((address & 0xFF00) == 0x7F00) + { + return m68k_lockup_r_8(address); + } + return (m68k_read_bus_8(address) | 0xFF); + } + + default: /* ZRAM */ + { + return zram[address & 0x1FFF]; + } + } +} + +unsigned int z80_read_word(unsigned int address) +{ + unsigned int data = z80_read_byte(address); + return (data | (data << 8)); +} + +void z80_write_byte(unsigned int address, unsigned int data) +{ + switch ((address >> 13) & 3) + { + case 2: /* YM2612 */ + { + fm_write(m68k.cycles, address & 3, data); + return; + } + + case 3: + { + switch ((address >> 8) & 0x7F) + { + case 0x60: /* Bank register */ + { + gen_zbank_w(data & 1); + return; + } + + case 0x7F: /* VDP */ + { + m68k_lockup_w_8(address, data); + return; + } + + default: + { + m68k_unused_8_w(address, data); + return; + } + } + } + + default: /* ZRAM */ + { + zram[address & 0x1FFF] = data; + m68k.cycles += 8; /* ZRAM access latency (fixes Pacman 2: New Adventures) */ + return; + } + } +} + +void z80_write_word(unsigned int address, unsigned int data) +{ + z80_write_byte(address, data >> 8); +} + + +/*--------------------------------------------------------------------------*/ +/* I/O Control */ +/*--------------------------------------------------------------------------*/ + +static void m68k_poll_detect(unsigned int reg_mask) +{ + /* detect MAIN-CPU register polling */ + if (m68k.poll.detected & reg_mask) + { + if (m68k.cycles <= m68k.poll.cycle) + { + if (m68k.pc == m68k.poll.pc) + { + /* MAIN-CPU polling confirmed ? */ + if (m68k.poll.detected & 1) + { + /* idle MAIN-CPU until register is modified */ + m68k.cycles = m68k.cycle_end; + m68k.stopped = reg_mask; +#ifdef LOG_SCD + error("m68k stopped from %d cycles\n", m68k.cycles); +#endif + } + else + { + /* confirm MAIN-CPU polling */ + m68k.poll.detected |= 1; + m68k.poll.cycle = m68k.cycles + 840; + } + } + return; + } + } + else + { + /* set MAIN-CPU register access flag */ + m68k.poll.detected = reg_mask; + } + + /* reset MAIN-CPU polling detection */ + m68k.poll.cycle = m68k.cycles + 840; + m68k.poll.pc = m68k.pc; +} + +static void m68k_poll_sync(unsigned int reg_mask) +{ + /* relative SUB-CPU cycle counter */ + unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; + + /* sync SUB-CPU with MAIN-CPU */ + if (!s68k.stopped) + { + s68k_run(cycles); + } + + /* SUB-CPU idle on register polling ? */ + if (s68k.stopped & reg_mask) + { + /* sync SUB-CPU with MAIN-CPU */ + s68k.cycles = cycles; + + /* restart SUB-CPU */ + s68k.stopped = 0; +#ifdef LOG_SCD + error("s68k started from %d cycles\n", cycles); +#endif + } + + /* clear CPU register access flags */ + s68k.poll.detected &= ~reg_mask; + m68k.poll.detected &= ~reg_mask; +} + +unsigned int ctrl_io_read_byte(unsigned int address) +{ + switch ((address >> 8) & 0xFF) + { + case 0x00: /* I/O chip */ + { + if (!(address & 0xE0)) + { + return io_68k_read((address >> 1) & 0x0F); + } + return m68k_read_bus_8(address); + } + + case 0x11: /* Z80 BUSACK */ + { + if (!(address & 1)) + { + /* Unused bits return prefetched bus data (Time Killers) */ + address = m68k.pc; + + /* Check if bus has been requested and is not reseted */ + if (zstate == 3) + { + /* D0 is cleared */ + return (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) & 0xFE); + } + + /* D0 is set */ + return (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) | 0x01); + } + return m68k_read_bus_8(address); + } + + case 0x20: /* MEGA-CD */ + { +#ifdef LOG_SCD + error("[%d][%d]read byte CD register %X (%X)\n", v_counter, m68k.cycles, address, m68k.pc); +#endif + if (system_hw == SYSTEM_MCD) + { + /* register index ($A12000-A1203F mirrored up to $A120FF) */ + uint8 index = address & 0x3f; + + /* Memory Mode */ + if (index == 0x03) + { + m68k_poll_detect(1<<0x03); + return scd.regs[0x03>>1].byte.l; + } + + /* SUB-CPU communication flags */ + if (index == 0x0f) + { + if (!s68k.stopped) + { + /* relative SUB-CPU cycle counter */ + unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; + + /* sync SUB-CPU with MAIN-CPU (Dracula Unleashed w/ Sega CD Model 2 Boot ROM) */ + s68k_run(cycles); + } + + m68k_poll_detect(1<<0x0f); + return scd.regs[0x0f>>1].byte.l; + } + + /* default registers */ + if (index < 0x30) + { + /* SUB-CPU communication words */ + if (index >= 0x20) + { + m68k_poll_detect(1 << (index - 0x10)); + } + + /* register LSB */ + if (address & 1) + { + return scd.regs[index >> 1].byte.l; + } + + /* register MSB */ + return scd.regs[index >> 1].byte.h; + } + } + + return m68k_read_bus_8(address); + } + + case 0x30: /* TIME */ + { + if (cart.hw.time_r) + { + unsigned int data = cart.hw.time_r(address); + if (address & 1) + { + return (data & 0xFF); + } + return (data >> 8); + } + return m68k_read_bus_8(address); + } + + case 0x41: /* BOOT ROM */ + { + if ((config.bios & 1) && (address & 1)) + { + unsigned int data = gen_bankswitch_r() & 1; + + /* Unused bits return prefetched bus data */ + address = m68k.pc; + data |= (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) & 0xFE); + return data; + } + return m68k_read_bus_8(address); + } + + case 0x10: /* MEMORY MODE */ + case 0x12: /* Z80 RESET */ + case 0x13: /* unknown */ + case 0x40: /* TMSS */ + case 0x44: /* RADICA */ + case 0x50: /* SVP */ + { + return m68k_read_bus_8(address); + } + + default: /* Invalid address */ + { + return m68k_lockup_r_8(address); + } + } +} + +unsigned int ctrl_io_read_word(unsigned int address) +{ + switch ((address >> 8) & 0xFF) + { + case 0x00: /* I/O chip */ + { + if (!(address & 0xE0)) + { + unsigned int data = io_68k_read((address >> 1) & 0x0F); + return (data << 8 | data); + } + return m68k_read_bus_16(address); + } + + case 0x11: /* Z80 BUSACK */ + { + /* Unused bits return prefetched bus data (Time Killers) */ + address = m68k.pc; + + /* Check if bus has been requested and is not reseted */ + if (zstate == 3) + { + /* D8 is cleared */ + return (*(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) & 0xFEFF); + } + + /* D8 is set */ + return (*(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) | 0x0100); + } + + case 0x20: /* MEGA-CD */ + { +#ifdef LOG_SCD + error("[%d][%d]read word CD register %X (%X)\n", v_counter, m68k.cycles, address, m68k.pc); +#endif + if (system_hw == SYSTEM_MCD) + { + /* register index ($A12000-A1203F mirrored up to $A120FF) */ + uint8 index = address & 0x3f; + + /* Memory Mode */ + if (index == 0x02) + { + m68k_poll_detect(1<<0x03); + return scd.regs[0x03>>1].w; + } + + /* CDC host data (word access only ?) */ + if (index == 0x08) + { + return cdc_host_r(); + } + + /* H-INT vector (word access only ?) */ + if (index == 0x06) + { + return *(uint16 *)(m68k.memory_map[0].base + 0x72); + } + + /* Stopwatch counter (word read access only ?) */ + if (index == 0x0c) + { + /* relative SUB-CPU cycle counter */ + unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; + + /* cycle-accurate counter value */ + return (scd.regs[0x0c>>1].w + ((cycles - scd.stopwatch) / TIMERS_SCYCLES_RATIO)) & 0xfff; + } + + /* default registers */ + if (index < 0x30) + { + /* SUB-CPU communication words */ + if (index >= 0x20) + { + if (!s68k.stopped) + { + /* relative SUB-CPU cycle counter */ + unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; + + /* sync SUB-CPU with MAIN-CPU (Soul Star) */ + s68k_run(cycles); + } + + m68k_poll_detect(3 << (index - 0x10)); + } + + return scd.regs[index >> 1].w; + } + } + + /* invalid address */ + return m68k_read_bus_16(address); + } + + case 0x30: /* TIME */ + { + if (cart.hw.time_r) + { + return cart.hw.time_r(address); + } + return m68k_read_bus_16(address); + } + + case 0x50: /* SVP */ + { + if ((address & 0xFD) == 0) + { + return svp->ssp1601.gr[SSP_XST].byte.h; + } + + if ((address & 0xFF) == 4) + { + unsigned int data = svp->ssp1601.gr[SSP_PM0].byte.h; + svp->ssp1601.gr[SSP_PM0].byte.h &= ~1; + return data; + } + + return m68k_read_bus_16(address); + } + + case 0x10: /* MEMORY MODE */ + case 0x12: /* Z80 RESET */ + case 0x13: /* unknown */ + case 0x40: /* TMSS */ + case 0x41: /* BOOT ROM */ + case 0x44: /* RADICA */ + { + return m68k_read_bus_16(address); + } + + default: /* Invalid address */ + { + return m68k_lockup_r_16(address); + } + } +} + +void ctrl_io_write_byte(unsigned int address, unsigned int data) +{ + switch ((address >> 8) & 0xFF) + { + case 0x00: /* I/O chip */ + { + if ((address & 0xE1) == 0x01) + { + /* get /LWR only */ + io_68k_write((address >> 1) & 0x0F, data); + return; + } + m68k_unused_8_w(address, data); + return; + } + + case 0x11: /* Z80 BUSREQ */ + { + if (!(address & 1)) + { + gen_zbusreq_w(data & 1, m68k.cycles); + return; + } + m68k_unused_8_w(address, data); + return; + } + + case 0x12: /* Z80 RESET */ + { + if (!(address & 1)) + { + gen_zreset_w(data & 1, m68k.cycles); + return; + } + m68k_unused_8_w(address, data); + return; + } + + case 0x20: /* MEGA-CD */ + { +#ifdef LOG_SCD + error("[%d][%d]write byte CD register %X -> 0x%02X (%X)\n", v_counter, m68k.cycles, address, data, m68k.pc); +#endif + if (system_hw == SYSTEM_MCD) + { + /* register index ($A12000-A1203F mirrored up to $A120FF) */ + switch (address & 0x3f) + { + case 0x00: /* SUB-CPU interrupt */ + { + /* IFL2 bit */ + if (data & 0x01) + { + /* level 2 interrupt enabled ? */ + if (scd.regs[0x32>>1].byte.l & 0x04) + { + if (!s68k.stopped) + { + /* relative SUB-CPU cycle counter */ + unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; + + /* sync SUB-CPU with MAIN-CPU (Earnest Evans, Fhey Area) */ + s68k_run(cycles); + } + + /* set IFL2 flag */ + scd.regs[0x00].byte.h |= 0x01; + + /* trigger level 2 interrupt */ + scd.pending |= (1 << 2); + + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + + /* writing 0 does nothing */ + return; + } + + case 0x01: /* SUB-CPU control */ + { + /* RESET bit */ + if (data & 0x01) + { + /* trigger reset on 0->1 transition */ + if (!(scd.regs[0x00].byte.l & 0x01)) + { + /* reset SUB-CPU */ + s68k_pulse_reset(); + } + + /* BUSREQ bit */ + if (data & 0x02) + { + /* SUB-CPU bus requested */ + s68k_pulse_halt(); + } + else + { + /* SUB-CPU bus released */ + s68k_clear_halt(); + } + } + else + { + /* SUB-CPU is halted while !RESET is asserted */ + s68k_pulse_halt(); + } + + scd.regs[0x00].byte.l = data; + return; + } + + case 0x02: /* PRG-RAM Write Protection */ + { + scd.regs[0x02>>1].byte.h = data; + return; + } + + case 0x03: /* Memory mode */ + { + m68k_poll_sync(1<<0x03); + + /* PRG-RAM 128k bank mapped to $020000-$03FFFF (resp. $420000-$43FFFF) */ + m68k.memory_map[scd.cartridge.boot + 0x02].base = scd.prg_ram + ((data & 0xc0) << 11); + m68k.memory_map[scd.cartridge.boot + 0x03].base = m68k.memory_map[scd.cartridge.boot + 0x02].base + 0x10000; + + /* check current mode */ + if (scd.regs[0x03>>1].byte.l & 0x04) + { + /* DMNA bit */ + if (data & 0x02) + { + /* writing 1 to DMNA in 1M mode will return Word-RAM to SUB-CPU in 2M mode */ + scd.dmna = 1; + } + else + { + /* writing 0 to DMNA in 1M mode actually set DMNA bit */ + data |= 0x02; + + /* update BK0-1 & DMNA bits */ + scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0xc2) | (data & 0xc2); + return; + } + } + else + { + /* writing 0 in 2M mode does nothing */ + if (data & 0x02) + { + /* Word-RAM is assigned to SUB-CPU */ + scd.dmna = 1; + + /* clear RET bit */ + scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0xc3) | (data & 0xc2); + return; + } + } + + /* update BK0-1 bits */ + scd.regs[0x03>>1].byte.l = (scd.regs[0x02>>1].byte.l & ~0xc0) | (data & 0xc0); + return; + } + + case 0x0e: /* MAIN-CPU communication flags */ + case 0x0f: /* !LWR is ignored (Space Ace, Dragon's Lair) */ + { + m68k_poll_sync(1<<0x0e); + scd.regs[0x0e>>1].byte.h = data; + return; + } + + default: + { + /* MAIN-CPU communication words */ + if ((address & 0x30) == 0x10) + { + m68k_poll_sync(1 << (address & 0x1f)); + + /* register LSB */ + if (address & 1) + { + scd.regs[(address >> 1) & 0xff].byte.l = data; + return; + } + + /* register MSB */ + scd.regs[(address >> 1) & 0xff].byte.h = data; + return; + } + + /* invalid address */ + m68k_unused_8_w(address, data); + return; + } + } + } + + m68k_unused_8_w(address, data); + return; + } + + case 0x30: /* TIME */ + { + cart.hw.time_w(address, data); + return; + } + + case 0x41: /* BOOT ROM */ + { + if ((config.bios & 1) && (address & 1)) + { + gen_bankswitch_w(data & 1); + return; + } + m68k_unused_8_w(address, data); + return; + } + + case 0x10: /* MEMORY MODE */ + case 0x13: /* unknown */ + case 0x40: /* TMSS */ + case 0x44: /* RADICA */ + case 0x50: /* SVP */ + { + m68k_unused_8_w(address, data); + return; + } + + default: /* Invalid address */ + { + m68k_lockup_w_8(address, data); + return; + } + } +} + +void ctrl_io_write_word(unsigned int address, unsigned int data) +{ + switch ((address >> 8) & 0xFF) + { + case 0x00: /* I/O chip */ + { + if (!(address & 0xE0)) + { + io_68k_write((address >> 1) & 0x0F, data & 0xFF); + return; + } + m68k_unused_16_w(address, data); + return; + } + + case 0x11: /* Z80 BUSREQ */ + { + gen_zbusreq_w((data >> 8) & 1, m68k.cycles); + return; + } + + case 0x12: /* Z80 RESET */ + { + gen_zreset_w((data >> 8) & 1, m68k.cycles); + return; + } + + case 0x20: /* MEGA-CD */ + { +#ifdef LOG_SCD + error("[%d][%d]write word CD register %X -> 0x%04X (%X)\n", v_counter, m68k.cycles, address, data, m68k.pc); +#endif + if (system_hw == SYSTEM_MCD) + { + /* register index ($A12000-A1203F mirrored up to $A120FF) */ + switch (address & 0x3e) + { + case 0x00: /* SUB-CPU interrupt & control */ + { + /* RESET bit */ + if (data & 0x01) + { + /* trigger reset on 0->1 transition */ + if (!(scd.regs[0x00].byte.l & 0x01)) + { + /* reset SUB-CPU */ + s68k_pulse_reset(); + } + + /* BUSREQ bit */ + if (data & 0x02) + { + /* SUB-CPU bus requested */ + s68k_pulse_halt(); + } + else + { + /* SUB-CPU bus released */ + s68k_clear_halt(); + } + } + else + { + /* SUB-CPU is halted while !RESET is asserted */ + s68k_pulse_halt(); + } + + /* IFL2 bit */ + if (data & 0x100) + { + /* level 2 interrupt enabled ? */ + if (scd.regs[0x32>>1].byte.l & 0x04) + { + /* set IFL2 flag */ + scd.regs[0x00].byte.h |= 0x01; + + /* trigger level 2 interrupt */ + scd.pending |= (1 << 2); + + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + + /* update LSB only */ + scd.regs[0x00].byte.l = data & 0xff; + return; + } + + case 0x02: /* Memory Mode */ + { + m68k_poll_sync(1<<0x03); + + /* PRG-RAM 128k bank mapped to $020000-$03FFFF (resp. $420000-$43FFFF) */ + m68k.memory_map[scd.cartridge.boot + 0x02].base = scd.prg_ram + ((data & 0xc0) << 11); + m68k.memory_map[scd.cartridge.boot + 0x03].base = m68k.memory_map[scd.cartridge.boot + 0x02].base + 0x10000; + + /* check current mode */ + if (scd.regs[0x03>>1].byte.l & 0x04) + { + /* DMNA bit */ + if (data & 0x02) + { + /* writing 1 to DMNA in 1M mode will return Word-RAM to SUB-CPU in 2M mode */ + scd.dmna = 1; + } + else + { + /* writing 0 to DMNA in 1M mode actually set DMNA bit */ + data |= 0x02; + + /* update WP0-7, BK0-1 & DMNA bits */ + scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc2) | (data & 0xffc2); + return; + } + } + else + { + /* writing 0 in 2M mode does nothing */ + if (data & 0x02) + { + /* Word-RAM is assigned to SUB-CPU */ + scd.dmna = 1; + + /* clear RET bit */ + scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc3) | (data & 0xffc2); + return; + } + } + + /* update WP0-7 & BK0-1 bits */ + scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc0) | (data & 0xffc0); + return; + } + + case 0x06: /* H-INT vector (word access only ?) */ + { + *(uint16 *)(m68k.memory_map[0].base + 0x72) = data; + return; + } + + case 0x0e: /* CPU communication flags */ + { + m68k_poll_sync(1<<0x0e); + + /* D8-D15 ignored -> only MAIN-CPU flags are updated (Mortal Kombat) */ + scd.regs[0x0e>>1].byte.h = data & 0xff; + return; + } + + default: + { + /* MAIN-CPU communication words */ + if ((address & 0x30) == 0x10) + { + m68k_poll_sync(3 << (address & 0x1e)); + scd.regs[(address >> 1) & 0xff].w = data; + return; + } + + /* invalid address */ + m68k_unused_16_w (address, data); + return; + } + } + } + + m68k_unused_16_w (address, data); + return; + } + + case 0x30: /* TIME */ + { + cart.hw.time_w(address, data); + return; + } + + case 0x40: /* TMSS */ + { + if (config.bios & 1) + { + gen_tmss_w(address & 3, data); + return; + } + m68k_unused_16_w(address, data); + return; + } + + case 0x50: /* SVP */ + { + if (!(address & 0xFD)) + { + svp->ssp1601.gr[SSP_XST].byte.h = data; + svp->ssp1601.gr[SSP_PM0].byte.h |= 2; + svp->ssp1601.emu_status &= ~SSP_WAIT_PM0; + return; + } + m68k_unused_16_w(address, data); + return; + } + + case 0x10: /* MEMORY MODE */ + case 0x13: /* unknown */ + case 0x41: /* BOOT ROM */ + case 0x44: /* RADICA */ + { + m68k_unused_16_w (address, data); + return; + } + + default: /* Invalid address */ + { + m68k_lockup_w_16 (address, data); + return; + } + } +} + + +/*--------------------------------------------------------------------------*/ +/* VDP */ +/*--------------------------------------------------------------------------*/ + +unsigned int vdp_read_byte(unsigned int address) +{ + switch (address & 0xFD) + { + case 0x00: /* DATA */ + { + return (vdp_68k_data_r() >> 8); + } + + case 0x01: /* DATA */ + { + return (vdp_68k_data_r() & 0xFF); + } + + case 0x04: /* CTRL */ + { + unsigned int data = (vdp_68k_ctrl_r(m68k.cycles) >> 8) & 3; + + /* Unused bits return prefetched bus data */ + address = m68k.pc; + data |= (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) & 0xFC); + + return data; + } + + case 0x05: /* CTRL */ + { + return (vdp_68k_ctrl_r(m68k.cycles) & 0xFF); + } + + case 0x08: /* HVC */ + case 0x0C: + { + return (vdp_hvc_r(m68k.cycles) >> 8); + } + + case 0x09: /* HVC */ + case 0x0D: + { + return (vdp_hvc_r(m68k.cycles) & 0xFF); + } + + case 0x18: /* Unused */ + case 0x19: + case 0x1C: + case 0x1D: + { + return m68k_read_bus_8(address); + } + + default: /* Invalid address */ + { + return m68k_lockup_r_8(address); + } + } +} + +unsigned int vdp_read_word(unsigned int address) +{ + switch (address & 0xFC) + { + case 0x00: /* DATA */ + { + return vdp_68k_data_r(); + } + + case 0x04: /* CTRL */ + { + unsigned int data = vdp_68k_ctrl_r(m68k.cycles) & 0x3FF; + + /* Unused bits return prefetched bus data */ + address = m68k.pc; + data |= (*(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) & 0xFC00); + + return data; + } + + case 0x08: /* HVC */ + case 0x0C: + { + return vdp_hvc_r(m68k.cycles); + } + + case 0x18: /* Unused */ + case 0x1C: + { + return m68k_read_bus_16(address); + } + + default: /* Invalid address */ + { + return m68k_lockup_r_16(address); + } + } +} + +void vdp_write_byte(unsigned int address, unsigned int data) +{ + switch (address & 0xFC) + { + case 0x00: /* Data port */ + { + vdp_68k_data_w(data << 8 | data); + return; + } + + case 0x04: /* Control port */ + { + vdp_68k_ctrl_w(data << 8 | data); + return; + } + + case 0x10: /* PSG */ + case 0x14: + { + if (address & 1) + { + SN76489_Write(m68k.cycles, data); + return; + } + m68k_unused_8_w(address, data); + return; + } + + case 0x18: /* Unused */ + { + m68k_unused_8_w(address, data); + return; + } + + case 0x1C: /* TEST register */ + { + vdp_test_w(data << 8 | data); + return; + } + + default: /* Invalid address */ + { + m68k_lockup_w_8(address, data); + return; + } + } +} + +void vdp_write_word(unsigned int address, unsigned int data) +{ + switch (address & 0xFC) + { + case 0x00: /* DATA */ + { + vdp_68k_data_w(data); + return; + } + + case 0x04: /* CTRL */ + { + vdp_68k_ctrl_w(data); + return; + } + + case 0x10: /* PSG */ + case 0x14: + { + SN76489_Write(m68k.cycles, data & 0xFF); + return; + } + + case 0x18: /* Unused */ + { + m68k_unused_16_w(address, data); + return; + } + + case 0x1C: /* Test register */ + { + vdp_test_w(data); + return; + } + + default: /* Invalid address */ + { + m68k_lockup_w_16 (address, data); + return; + } + } +} + + +/*--------------------------------------------------------------------------*/ +/* PICO (incomplete) */ +/*--------------------------------------------------------------------------*/ + +unsigned int pico_read_byte(unsigned int address) +{ + switch (address & 0xFF) + { + case 0x01: /* VERSION register */ + { + return (region_code >> 1); + } + + case 0x03: /* IO register */ + { + return ~input.pad[0]; + } + + case 0x05: /* PEN X coordinate (MSB) */ + { + return (input.analog[0][0] >> 8); + } + + case 0x07: /* PEN X coordinate (LSB) */ + { + return (input.analog[0][0] & 0xFF); + } + + case 0x09: /* PEN Y coordinate (MSB) */ + { + return (input.analog[0][1] >> 8); + } + + case 0x0B: /* PEN Y coordinate (LSB) */ + { + return (input.analog[0][1] & 0xFF); + } + + case 0x0D: /* PAGE register */ + { + return (1 << pico_current) - 1; + } + + case 0x10: /* ADPCM data registers (TODO) */ + case 0x11: + { + return 0xff; + } + + case 0x12: /* ADPCM control registers (TODO) */ + { + return 0x80; + } + + default: + { + return m68k_read_bus_8(address); + } + } +} + +unsigned int pico_read_word(unsigned int address) +{ + return (pico_read_byte(address | 1) | (pico_read_byte(address) << 8)); +} diff --git a/genplus-gx/core/mem68k.h b/genplus-gx/core/mem68k.h new file mode 100644 index 0000000000..1d8bc3bab3 --- /dev/null +++ b/genplus-gx/core/mem68k.h @@ -0,0 +1,77 @@ +/*************************************************************************************** + * Genesis Plus + * Main 68k bus handlers + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _MEM68K_H_ +#define _MEM68K_H_ + +/* unused areas */ +extern unsigned int m68k_read_bus_8(unsigned int address); +extern unsigned int m68k_read_bus_16(unsigned int address); +extern void m68k_unused_8_w(unsigned int address, unsigned int data); +extern void m68k_unused_16_w(unsigned int address, unsigned int data); + +/* illegal areas */ +extern unsigned int m68k_lockup_r_8(unsigned int address); +extern unsigned int m68k_lockup_r_16(unsigned int address); +extern void m68k_lockup_w_8(unsigned int address, unsigned int data); +extern void m68k_lockup_w_16(unsigned int address, unsigned int data); + +/* Z80 bus */ +extern unsigned int z80_read_byte(unsigned int address); +extern unsigned int z80_read_word(unsigned int address); +extern void z80_write_byte(unsigned int address, unsigned int data); +extern void z80_write_word(unsigned int address, unsigned int data); + +/* I/O & Control registers */ +extern unsigned int ctrl_io_read_byte(unsigned int address); +extern unsigned int ctrl_io_read_word(unsigned int address); +extern void ctrl_io_write_byte(unsigned int address, unsigned int data); +extern void ctrl_io_write_word(unsigned int address, unsigned int data); + +/* VDP */ +extern unsigned int vdp_read_byte(unsigned int address); +extern unsigned int vdp_read_word(unsigned int address); +extern void vdp_write_byte(unsigned int address, unsigned int data); +extern void vdp_write_word(unsigned int address, unsigned int data); + +/* PICO */ +extern unsigned int pico_read_byte(unsigned int address); +extern unsigned int pico_read_word(unsigned int address); + +#endif /* _MEM68K_H_ */ diff --git a/genplus-gx/core/membnk.c b/genplus-gx/core/membnk.c new file mode 100644 index 0000000000..64f16d83a1 --- /dev/null +++ b/genplus-gx/core/membnk.c @@ -0,0 +1,322 @@ +/*************************************************************************************** + * Genesis Plus + * Z80 bank access to 68k bus + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +/* + Handlers for access to unused addresses and those which make the + machine lock up. +*/ + +unsigned int zbank_unused_r(unsigned int address) +{ +#ifdef LOGERROR + error("Z80 bank unused read %06X (%x)\n", address, Z80.pc.d); +#endif + return 0xFF; +} + +void zbank_unused_w(unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error("Z80 bank unused write %06X = %02X (%x)\n", address, data, Z80.pc.d); +#endif +} + +unsigned int zbank_lockup_r(unsigned int address) +{ +#ifdef LOGERROR + error("Z80 bank lockup read %06X (%x)\n", address, Z80.pc.d); +#endif + if (!config.force_dtack) + { + Z80.cycles = 0xFFFFFFFF; + zstate = 0; + } + return 0xFF; +} + +void zbank_lockup_w(unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error("Z80 bank lockup write %06X = %02X (%x)\n", address, data, Z80.pc.d); +#endif + if (!config.force_dtack) + { + Z80.cycles = 0xFFFFFFFF; + zstate = 0; + } +} + +/* I/O & Control registers */ +unsigned int zbank_read_ctrl_io(unsigned int address) +{ + switch ((address >> 8) & 0xFF) + { + case 0x00: /* I/O chip */ + { + if (!(address & 0xE0)) + { + return (io_68k_read((address >> 1) & 0x0F)); + } + return zbank_unused_r(address); + } + + case 0x11: /* BUSACK */ + { + if (address & 1) + { + return zbank_unused_r(address); + } + return 0xFF; + } + + case 0x30: /* TIME */ + { + if (cart.hw.time_r) + { + unsigned int data = cart.hw.time_r(address); + if (address & 1) + { + return (data & 0xFF); + } + return (data >> 8); + } + return zbank_unused_r(address); + } + + case 0x41: /* OS ROM */ + { + if (address & 1) + { + return (gen_bankswitch_r() | 0xFE); + } + return zbank_unused_r(address); + } + + case 0x10: /* MEMORY MODE */ + case 0x12: /* RESET */ + case 0x20: /* MEGA-CD */ + case 0x40: /* TMSS */ + case 0x44: /* RADICA */ + case 0x50: /* SVP REGISTERS */ + { + return zbank_unused_r(address); + } + + default: /* Invalid address */ + { + return zbank_lockup_r(address); + } + } +} + +void zbank_write_ctrl_io(unsigned int address, unsigned int data) +{ + switch ((address >> 8) & 0xFF) + { + case 0x00: /* I/O chip */ + { + /* get /LWR only */ + if ((address & 0xE1) == 0x01) + { + io_68k_write((address >> 1) & 0x0F, data); + return; + } + zbank_unused_w(address, data); + return; + } + + case 0x11: /* BUSREQ */ + { + if (!(address & 1)) + { + gen_zbusreq_w(data & 1, Z80.cycles); + return; + } + zbank_unused_w(address, data); + return; + } + + case 0x12: /* RESET */ + { + if (!(address & 1)) + { + gen_zreset_w(data & 1, Z80.cycles); + return; + } + zbank_unused_w(address, data); + return; + } + + case 0x30: /* TIME */ + { + cart.hw.time_w(address, data); + return; + } + + case 0x41: /* OS ROM */ + { + if ((config.bios & 1) && (address & 1)) + { + gen_bankswitch_w(data & 1); + return; + } + zbank_unused_w(address, data); + return; + } + + case 0x10: /* MEMORY MODE */ + case 0x20: /* MEGA-CD */ + case 0x40: /* TMSS */ + case 0x44: /* RADICA */ + case 0x50: /* SVP REGISTERS */ + { + zbank_unused_w(address, data); + return; + } + + default: /* Invalid address */ + { + zbank_lockup_w(address, data); + return; + } + } +} + + +/* VDP */ +unsigned int zbank_read_vdp(unsigned int address) +{ + switch (address & 0xFD) + { + case 0x00: /* DATA */ + { + return (vdp_68k_data_r() >> 8); + } + + case 0x01: /* DATA */ + { + return (vdp_68k_data_r() & 0xFF); + } + + case 0x04: /* CTRL */ + { + return (((vdp_68k_ctrl_r(Z80.cycles) >> 8) & 3) | 0xFC); + } + + case 0x05: /* CTRL */ + { + return (vdp_68k_ctrl_r(Z80.cycles) & 0xFF); + } + + case 0x08: /* HVC */ + case 0x0C: + { + return (vdp_hvc_r(Z80.cycles) >> 8); + } + + case 0x09: /* HVC */ + case 0x0D: + { + return (vdp_hvc_r(Z80.cycles) & 0xFF); + } + + case 0x18: /* Unused */ + case 0x19: + case 0x1C: + case 0x1D: + { + return zbank_unused_r(address); + } + + default: /* Invalid address */ + { + return zbank_lockup_r(address); + } + } +} + +void zbank_write_vdp(unsigned int address, unsigned int data) +{ + switch (address & 0xFC) + { + case 0x00: /* Data port */ + { + vdp_68k_data_w(data << 8 | data); + return; + } + + case 0x04: /* Control port */ + { + vdp_68k_ctrl_w(data << 8 | data); + return; + } + + case 0x10: /* PSG */ + case 0x14: + { + if (address & 1) + { + SN76489_Write(Z80.cycles, data); + return; + } + zbank_unused_w(address, data); + return; + } + + case 0x18: /* Unused */ + { + zbank_unused_w(address, data); + return; + } + + case 0x1C: /* TEST register */ + { + vdp_test_w(data << 8 | data); + return; + } + + default: /* Invalid address */ + { + zbank_lockup_w(address, data); + return; + } + } +} diff --git a/genplus-gx/core/membnk.h b/genplus-gx/core/membnk.h new file mode 100644 index 0000000000..b4b242e2e0 --- /dev/null +++ b/genplus-gx/core/membnk.h @@ -0,0 +1,58 @@ +/*************************************************************************************** + * Genesis Plus + * Z80 bank access to 68k bus + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _MEMBNK_H_ +#define _MEMBNK_H_ + +extern unsigned int zbank_unused_r(unsigned int address); +extern void zbank_unused_w(unsigned int address, unsigned int data); +extern unsigned int zbank_lockup_r(unsigned int address); +extern void zbank_lockup_w(unsigned int address, unsigned int data); +extern unsigned int zbank_read_ctrl_io(unsigned int address); +extern void zbank_write_ctrl_io(unsigned int address, unsigned int data); +extern unsigned int zbank_read_vdp(unsigned int address); +extern void zbank_write_vdp(unsigned int address, unsigned int data); + +struct _zbank_memory_map +{ + unsigned int (*read)(unsigned int address); + void (*write)(unsigned int address, unsigned int data); +} zbank_memory_map[256]; + +#endif /* _MEMBNK_H_ */ diff --git a/genplus-gx/core/memz80.c b/genplus-gx/core/memz80.c new file mode 100644 index 0000000000..3a5d9b291e --- /dev/null +++ b/genplus-gx/core/memz80.c @@ -0,0 +1,682 @@ +/*************************************************************************************** + * Genesis Plus + * Z80 bus handlers (Genesis & Master System modes) + * + * Support for SG-1000, Mark-III, Master System, Game Gear & Mega Drive ports access + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + + +/*--------------------------------------------------------------------------*/ +/* Handlers for access to unused addresses and those which make the */ +/* machine lock up. */ +/*--------------------------------------------------------------------------*/ + +INLINE void z80_unused_w(unsigned int address, unsigned char data) +{ +#ifdef LOGERROR + error("Z80 unused write %04X = %02X (%x)\n", address, data, Z80.pc.w.l); +#endif +} + +INLINE unsigned char z80_unused_r(unsigned int address) +{ +#ifdef LOGERROR + error("Z80 unused read %04X (%x)\n", address, Z80.pc.w.l); +#endif + return 0xFF; +} + +INLINE void z80_lockup_w(unsigned int address, unsigned char data) +{ +#ifdef LOGERROR + error("Z80 lockup write %04X = %02X (%x)\n", address, data, Z80.pc.w.l); +#endif + if (!config.force_dtack) + { + Z80.cycles = 0xFFFFFFFF; + zstate = 0; + } +} + +INLINE unsigned char z80_lockup_r(unsigned int address) +{ +#ifdef LOGERROR + error("Z80 lockup read %04X (%x)\n", address, Z80.pc.w.l); +#endif + if (!config.force_dtack) + { + Z80.cycles = 0xFFFFFFFF; + zstate = 0; + } + return 0xFF; +} + + +/*--------------------------------------------------------------------------*/ +/* Z80 Memory handlers (Genesis mode) */ +/*--------------------------------------------------------------------------*/ + +unsigned char z80_memory_r(unsigned int address) +{ + switch((address >> 13) & 7) + { + case 0: /* $0000-$3FFF: Z80 RAM (8K mirrored) */ + case 1: + { + return zram[address & 0x1FFF]; + } + + case 2: /* $4000-$5FFF: YM2612 */ + { + return fm_read(Z80.cycles, address & 3); + } + + case 3: /* $7F00-$7FFF: VDP */ + { + if ((address >> 8) == 0x7F) + { + return (*zbank_memory_map[0xc0].read)(address); + } + return z80_unused_r(address); + } + + default: /* $8000-$FFFF: 68k bank (32K) */ + { + address = zbank | (address & 0x7FFF); + if (zbank_memory_map[address >> 16].read) + { + return (*zbank_memory_map[address >> 16].read)(address); + } + return READ_BYTE(m68k.memory_map[address >> 16].base, address & 0xFFFF); + } + } +} + + +void z80_memory_w(unsigned int address, unsigned char data) +{ + switch((address >> 13) & 7) + { + case 0: /* $0000-$3FFF: Z80 RAM (8K mirrored) */ + case 1: + { + zram[address & 0x1FFF] = data; + return; + } + + case 2: /* $4000-$5FFF: YM2612 */ + { + fm_write(Z80.cycles, address & 3, data); + return; + } + + case 3: /* Bank register and VDP */ + { + switch(address >> 8) + { + case 0x60: /* $6000-$60FF: Bank register */ + { + gen_zbank_w(data & 1); + return; + } + + case 0x7F: /* $7F00-$7FFF: VDP */ + { + (*zbank_memory_map[0xc0].write)(address, data); + return; + } + + default: + { + z80_unused_w(address, data); + return; + } + } + } + + default: /* $8000-$FFFF: 68k bank (32K) */ + { + address = zbank | (address & 0x7FFF); + if (zbank_memory_map[address >> 16].write) + { + (*zbank_memory_map[address >> 16].write)(address, data); + return; + } + WRITE_BYTE(m68k.memory_map[address >> 16].base, address & 0xFFFF, data); + return; + } + } +} + +/*--------------------------------------------------------------------------*/ +/* Unused Port handlers */ +/* */ +/* Ports are unused when not in Mark III compatibility mode. */ +/* */ +/* Genesis games that access ports anyway: */ +/* Thunder Force IV reads port $BF in it's interrupt handler. */ +/* */ +/*--------------------------------------------------------------------------*/ + +unsigned char z80_unused_port_r(unsigned int port) +{ +#if LOGERROR + error("Z80 unused read from port %04X (%x)\n", port, Z80.pc.w.l); +#endif + if (system_hw == SYSTEM_SMS) + { + unsigned int address = (Z80.pc.w.l - 1) & 0xFFFF; + return z80_readmap[address >> 10][address & 0x3FF]; + } + return 0xFF; +} + +void z80_unused_port_w(unsigned int port, unsigned char data) +{ +#if LOGERROR + error("Z80 unused write to port %04X = %02X (%x)\n", port, data, Z80.pc.w.l); +#endif +} + +/*--------------------------------------------------------------------------*/ +/* MegaDrive / Genesis port handlers (Master System compatibility mode) */ +/*--------------------------------------------------------------------------*/ + +void z80_md_port_w(unsigned int port, unsigned char data) +{ + switch (port & 0xC1) + { + case 0x01: + { + io_z80_write(1, data, Z80.cycles + PBC_CYCLE_OFFSET); + return; + } + + case 0x40: + case 0x41: + { + SN76489_Write(Z80.cycles, data); + return; + } + + case 0x80: + { + vdp_z80_data_w(data); + return; + } + + case 0x81: + { + vdp_z80_ctrl_w(data); + return; + } + + default: + { + port &= 0xFF; + + if ((port >= 0xF0) && (config.ym2413 & 1)) + { + fm_write(Z80.cycles, port&3, data); + return; + } + + z80_unused_port_w(port, data); + return; + } + } +} + +unsigned char z80_md_port_r(unsigned int port) +{ + switch (port & 0xC1) + { + case 0x40: + { + return ((vdp_hvc_r(Z80.cycles - 15) >> 8) & 0xFF); + } + + case 0x41: + { + return (vdp_hvc_r(Z80.cycles - 15) & 0xFF); + } + + case 0x80: + { + return vdp_z80_data_r(); + } + + case 0x81: + { + return vdp_z80_ctrl_r(Z80.cycles); + } + + default: + { + port &= 0xFF; + + if ((port == 0xC0) || (port == 0xC1) || (port == 0xDC) || (port == 0xDD)) + { + return io_z80_read(port & 1); + } + + /* read FM chip if enabled */ + if ((port >= 0xF0) && (config.ym2413 & 1)) + { + return YM2413Read(port & 3); + } + + return z80_unused_port_r(port); + } + } +} + + +/*--------------------------------------------------------------------------*/ +/* Game Gear port handlers */ +/*--------------------------------------------------------------------------*/ + +void z80_gg_port_w(unsigned int port, unsigned char data) +{ + switch(port & 0xC1) + { + case 0x00: + case 0x01: + { + port &= 0xFF; + + if (port < 0x07) + { + if (system_hw == SYSTEM_GG) + { + io_gg_write(port, data); + return; + } + + z80_unused_port_w(port & 0xFF, data); + return; + } + + io_z80_write(port & 1, data, Z80.cycles + SMS_CYCLE_OFFSET); + return; + } + + case 0x40: + case 0x41: + { + SN76489_Write(Z80.cycles, data); + return; + } + + case 0x80: + { + vdp_z80_data_w(data); + return; + } + + case 0x81: + { + vdp_sms_ctrl_w(data); + return; + } + + default: + { + z80_unused_port_w(port & 0xFF, data); + return; + } + } +} + +unsigned char z80_gg_port_r(unsigned int port) +{ + switch(port & 0xC1) + { + case 0x00: + case 0x01: + { + port &= 0xFF; + + if (port < 0x07) + { + if (system_hw == SYSTEM_GG) + { + return io_gg_read(port); + } + } + + return z80_unused_port_r(port); + } + + case 0x40: + { + return ((vdp_hvc_r(Z80.cycles) >> 8) & 0xFF); + } + + case 0x41: + { + return (vdp_hvc_r(Z80.cycles) & 0xFF); + } + + case 0x80: + { + return vdp_z80_data_r(); + } + + case 0x81: + { + return vdp_z80_ctrl_r(Z80.cycles); + } + + default: + { + port &= 0xFF; + + if ((port == 0xC0) || (port == 0xC1) || (port == 0xDC) || (port == 0xDD)) + { + return io_z80_read(port & 1); + } + + return z80_unused_port_r(port); + } + } +} + + +/*--------------------------------------------------------------------------*/ +/* Master System port handlers */ +/*--------------------------------------------------------------------------*/ + +void z80_ms_port_w(unsigned int port, unsigned char data) +{ + switch (port & 0xC1) + { + case 0x00: + case 0x01: + { + io_z80_write(port & 1, data, Z80.cycles + SMS_CYCLE_OFFSET); + return; + } + + case 0x40: + case 0x41: + { + SN76489_Write(Z80.cycles, data); + return; + } + + case 0x80: + { + vdp_z80_data_w(data); + return; + } + + case 0x81: + { + vdp_sms_ctrl_w(data); + return; + } + + default: + { + if (!(port & 4) && (config.ym2413 & 1)) + { + fm_write(Z80.cycles, port & 3, data); + return; + } + + z80_unused_port_w(port & 0xFF, data); + return; + } + } +} + +unsigned char z80_ms_port_r(unsigned int port) +{ + switch (port & 0xC1) + { + case 0x00: + case 0x01: + { + return z80_unused_port_r(port & 0xFF); + } + + case 0x40: + { + return ((vdp_hvc_r(Z80.cycles) >> 8) & 0xFF); + } + + case 0x41: + { + return (vdp_hvc_r(Z80.cycles) & 0xFF); + } + + case 0x80: + { + return vdp_z80_data_r(); + } + + case 0x81: + { + return vdp_z80_ctrl_r(Z80.cycles); + } + + default: + { + /* read FM chip if enabled */ + if (!(port & 4) && (config.ym2413 & 1)) + { + /* check if I/O ports are disabled */ + if (io_reg[0x0E] & 0x04) + { + return YM2413Read(port & 3); + } + else + { + return YM2413Read(port & 3) & io_z80_read(port & 1); + } + } + + /* check if I/O ports are enabled */ + if (!(io_reg[0x0E] & 0x04)) + { + return io_z80_read(port & 1); + } + + return z80_unused_port_r(port & 0xFF); + } + } +} + + +/*--------------------------------------------------------------------------*/ +/* Mark III port handlers */ +/*--------------------------------------------------------------------------*/ + +void z80_m3_port_w(unsigned int port, unsigned char data) +{ + switch (port & 0xC1) + { + case 0x00: + case 0x01: + { + z80_unused_port_w(port, data); + return; + } + + case 0x40: + case 0x41: + { + SN76489_Write(Z80.cycles, data); + return; + } + + case 0x80: + { + vdp_z80_data_w(data); + return; + } + + case 0x81: + { + vdp_sms_ctrl_w(data); + return; + } + + default: + { + if (!(port & 4) && (config.ym2413 & 1)) + { + fm_write(Z80.cycles, port & 3, data); + return; + } + + z80_unused_port_w(port & 0xFF, data); + return; + } + } +} + +unsigned char z80_m3_port_r(unsigned int port) +{ + switch (port & 0xC1) + { + case 0x00: + case 0x01: + { + return z80_unused_port_r(port & 0xFF); + } + + case 0x40: + { + return ((vdp_hvc_r(Z80.cycles) >> 8) & 0xFF); + } + + case 0x41: + { + return (vdp_hvc_r(Z80.cycles) & 0xFF); + } + + case 0x80: + { + return vdp_z80_data_r(); + } + + case 0x81: + { + return vdp_z80_ctrl_r(Z80.cycles); + } + + default: + { + /* read FM chip if enabled */ + if (!(port & 4) && (config.ym2413 & 1)) + { + /* I/O ports are automatically disabled */ + return YM2413Read(port & 3); + } + + /* read I/O ports */ + return io_z80_read(port & 1); + } + } +} + + +/*--------------------------------------------------------------------------*/ +/* SG-1000 port handlers */ +/*--------------------------------------------------------------------------*/ + +void z80_sg_port_w(unsigned int port, unsigned char data) +{ + switch(port & 0xC1) + { + case 0x40: + case 0x41: + { + SN76489_Write(Z80.cycles, data); + return; + } + + case 0x80: + { + vdp_z80_data_w(data); + return; + } + + case 0x81: + { + vdp_tms_ctrl_w(data); + return; + } + + default: + { + z80_unused_port_w(port & 0xFF, data); + return; + } + } +} + +unsigned char z80_sg_port_r(unsigned int port) +{ + switch (port & 0xC1) + { + case 0x80: + { + return vdp_z80_data_r(); + } + + case 0x81: + { + return vdp_z80_ctrl_r(Z80.cycles); + } + + case 0xC0: + case 0xC1: + { + return io_z80_read(port & 1); + } + + default: + { + return z80_unused_port_r(port); + } + } +} diff --git a/genplus-gx/core/memz80.h b/genplus-gx/core/memz80.h new file mode 100644 index 0000000000..27207f33e7 --- /dev/null +++ b/genplus-gx/core/memz80.h @@ -0,0 +1,60 @@ +/*************************************************************************************** + * Genesis Plus + * Z80 bus handlers (Genesis & Master System modes) + * + * Support for SG-1000, Mark-III, Master System, Game Gear & Mega Drive ports access + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _MEMZ80_H_ +#define _MEMZ80_H_ + +extern unsigned char z80_memory_r(unsigned int address); +extern void z80_memory_w(unsigned int address, unsigned char data); +extern unsigned char z80_unused_port_r(unsigned int port); +extern void z80_unused_port_w(unsigned int port, unsigned char data); +extern unsigned char z80_md_port_r(unsigned int port); +extern void z80_md_port_w(unsigned int port, unsigned char data); +extern unsigned char z80_gg_port_r(unsigned int port); +extern void z80_gg_port_w(unsigned int port, unsigned char data); +extern unsigned char z80_ms_port_r(unsigned int port); +extern void z80_ms_port_w(unsigned int port, unsigned char data); +extern unsigned char z80_m3_port_r(unsigned int port); +extern void z80_m3_port_w(unsigned int port, unsigned char data); +extern unsigned char z80_sg_port_r(unsigned int port); +extern void z80_sg_port_w(unsigned int port, unsigned char data); + +#endif /* _MEMZ80_H_ */ diff --git a/genplus-gx/core/ntsc/changes.txt b/genplus-gx/core/ntsc/changes.txt new file mode 100644 index 0000000000..7fd8b4f985 --- /dev/null +++ b/genplus-gx/core/ntsc/changes.txt @@ -0,0 +1,96 @@ +sms_ntsc Change Log +------------------- + +sms_ntsc 0.2.3 +-------------- +- Moved configuration options to sms_ntsc_config.h, making it easier to +manage + +- Greatly clarified and improved demo to read any uncompressed BMP image +and write filtered image when done + +- Improved gamma to be properly applied to each RGB channel, and changed +default to compensate for difference between PC monitor and TV gamma + +- Improved contrast to be properly applied to each RGB channel rather +than just luma + +- Improved floating point calculations in library to be more stable and +not need double precision, which was causing problems with the sharpness +control on Windows when the DirectX libraries changed the FPU to single +precision mode + +- Added extern "C" to header, allowing use in C++ without having to +rename the source file + +- Made internal changes to factor out code common from all my NTSC +filter libraries, greatly simplifying things for me + + +sms_ntsc 0.2.2 +-------------- +- Changed sms_ntsc_blit() again, this time to always take a pixel count +for input pitch (since the type is known) and a byte count for the +output pitch (since it can output at multiple depths now). I think I've +got the right interface this time. :) + +- Improved default blitter to have selectable input and output pixel +formats + +- Added parameters for resolution, color bleed, and artifacts + +- Added presets for composite video, S-video, RGB, and monochrome + +- Added SMS_NTSC_OUT_WIDTH() and SMS_NTSC_IN_WIDTH() for calculating +input/output widths + +- Improved demo with more controls and interpolation and darkening of +scanlines rather than duplicating them + +- Improved documentation + +- Interface changes: sms_ntsc_blit() takes output pitch in bytes again. +Sorry for the multiple changes; I think I got it right this time. :) + +- Removed: SMS_NTSC_CALC_WIDTH (use SMS_NTSC_OUT_WIDTH) + + +sms_ntsc 0.2.1 +-------------- +- Added parameters for color fringing and edge artifacts + + +sms_ntsc 0.2.0 +-------------- +- Changed sms_ntsc_blit() to take pixel counts instead of byte counts +for in_pitch and out_pitch, making it simpler to use. This requires that +current code be updated. + +- Significantly improved NTSC signal processing to give clearer image +and better sharpness control + +- Reduced scrolling shimmer and color artifacts to be closer to what +console generates + +- Added gamma curve parameter to allow better matching of darker colors +on a TV + +- Added ability to generate matching RGB palette for use in a normal +blitter + + +sms_ntsc 0.1.1 +-------------- +- Changed sms_ntsc_blit() to accept 12-bit BGR pixels instead of palette +indicies and a separate palette. + +- Improved sms_ntsc_blit() to accept any input width, allowing all the +different screen widths to be handled without complication. Use +SMS_NTSC_CALC_WIDTH() to find the output width for a given input width. + +- Added toggling of left 8 column display to demo + + +sms_ntsc 0.1.0 +-------------- +- First version diff --git a/genplus-gx/core/ntsc/license.txt b/genplus-gx/core/ntsc/license.txt new file mode 100644 index 0000000000..5faba9d48c --- /dev/null +++ b/genplus-gx/core/ntsc/license.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/genplus-gx/core/ntsc/md_ntsc.c b/genplus-gx/core/ntsc/md_ntsc.c new file mode 100644 index 0000000000..3859cfd58b --- /dev/null +++ b/genplus-gx/core/ntsc/md_ntsc.c @@ -0,0 +1,143 @@ +/* md_ntsc 0.1.2. http://www.slack.net/~ant/ */ + +/* Modified for use with Genesis Plus GX -- EkeEke */ + +#include "shared.h" +#include "md_ntsc.h" + +/* Copyright (C) 2006 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +md_ntsc_setup_t const md_ntsc_monochrome = { 0,-1, 0, 0,.2, 0, 0,-.2,-.2,-1, 0, 0 }; +md_ntsc_setup_t const md_ntsc_composite = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +md_ntsc_setup_t const md_ntsc_svideo = { 0, 0, 0, 0, 0, 0,.2, -1, -1, 0, 0, 0 }; +md_ntsc_setup_t const md_ntsc_rgb = { 0, 0, 0, 0,.2, 0,.7, -1, -1,-1, 0, 0 }; + +#define alignment_count 2 +#define burst_count 1 +#define rescale_in 1 +#define rescale_out 1 + +#define artifacts_mid 0.40f +#define fringing_mid 0.30f +#define std_decoder_hue 0 + +#define gamma_size 8 +#define artifacts_max 1.00f +#define LUMA_CUTOFF 0.1974 + +#include "md_ntsc_impl.h" + +/* 2 input pixels -> 4 composite samples */ +pixel_info_t const md_ntsc_pixels [alignment_count] = { + { PIXEL_OFFSET( -4, -9 ), { 0.1f, 0.9f, 0.9f, 0.1f } }, + { PIXEL_OFFSET( -2, -7 ), { 0.1f, 0.9f, 0.9f, 0.1f } }, +}; + +static void correct_errors( md_ntsc_rgb_t color, md_ntsc_rgb_t* out ) +{ + unsigned i; + for ( i = 0; i < rgb_kernel_size / 4; i++ ) + { + md_ntsc_rgb_t error = color - + out [i ] - out [i + 2 +16] - out [i + 4 ] - out [i + 6 +16] - + out [i + 8] - out [(i+10)%16+16] - out [(i+12)%16] - out [(i+14)%16+16]; + CORRECT_ERROR( i + 6 + 16 ); + /*DISTRIBUTE_ERROR( 2+16, 4, 6+16 );*/ + } +} + +void md_ntsc_init( md_ntsc_t* ntsc, md_ntsc_setup_t const* setup ) +{ + int entry; + init_t impl; + if ( !setup ) + setup = &md_ntsc_composite; + init( &impl, setup ); + + for ( entry = 0; entry < md_ntsc_palette_size; entry++ ) + { + float bb = impl.to_float [entry >> 6 & 7]; + float gg = impl.to_float [entry >> 3 & 7]; + float rr = impl.to_float [entry & 7]; + + float y, i, q = RGB_TO_YIQ( rr, gg, bb, y, i ); + + int r, g, b = YIQ_TO_RGB( y, i, q, impl.to_rgb, int, r, g ); + md_ntsc_rgb_t rgb = PACK_RGB( r, g, b ); + + if ( setup->palette_out ) + RGB_PALETTE_OUT( rgb, &setup->palette_out [entry * 3] ); + + if ( ntsc ) + { + gen_kernel( &impl, y, i, q, ntsc->table [entry] ); + correct_errors( rgb, ntsc->table [entry] ); + } + } +} + +#ifndef CUSTOM_BLITTER +void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input, + int in_width, int vline) +{ + int const chunk_count = in_width / md_ntsc_in_chunk - 1; + + /* use palette entry 0 for unused pixels */ + MD_NTSC_IN_T border = table[0]; + + MD_NTSC_BEGIN_ROW( ntsc, border, + MD_NTSC_ADJ_IN( table[*input++] ), + MD_NTSC_ADJ_IN( table[*input++] ), + MD_NTSC_ADJ_IN( table[*input++] ) ); + + md_ntsc_out_t* restrict line_out = (md_ntsc_out_t*)(&bitmap.data[(vline * bitmap.pitch)]); + + int n; + + for ( n = chunk_count; n; --n ) + { + /* order of input and output pixels must not be altered */ + MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) ); + MD_NTSC_RGB_OUT( 0, *line_out++ ); + MD_NTSC_RGB_OUT( 1, *line_out++ ); + + MD_NTSC_COLOR_IN( 1, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) ); + MD_NTSC_RGB_OUT( 2, *line_out++ ); + MD_NTSC_RGB_OUT( 3, *line_out++ ); + + MD_NTSC_COLOR_IN( 2, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) ); + MD_NTSC_RGB_OUT( 4, *line_out++ ); + MD_NTSC_RGB_OUT( 5, *line_out++ ); + + MD_NTSC_COLOR_IN( 3, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) ); + MD_NTSC_RGB_OUT( 6, *line_out++ ); + MD_NTSC_RGB_OUT( 7, *line_out++ ); + } + + /* finish final pixels */ + MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) ); + MD_NTSC_RGB_OUT( 0, *line_out++ ); + MD_NTSC_RGB_OUT( 1, *line_out++ ); + + MD_NTSC_COLOR_IN( 1, ntsc, border ); + MD_NTSC_RGB_OUT( 2, *line_out++ ); + MD_NTSC_RGB_OUT( 3, *line_out++ ); + + MD_NTSC_COLOR_IN( 2, ntsc, border ); + MD_NTSC_RGB_OUT( 4, *line_out++ ); + MD_NTSC_RGB_OUT( 5, *line_out++ ); + + MD_NTSC_COLOR_IN( 3, ntsc, border ); + MD_NTSC_RGB_OUT( 6, *line_out++ ); + MD_NTSC_RGB_OUT( 7, *line_out++ ); +} +#endif diff --git a/genplus-gx/core/ntsc/md_ntsc.h b/genplus-gx/core/ntsc/md_ntsc.h new file mode 100644 index 0000000000..d2c6350728 --- /dev/null +++ b/genplus-gx/core/ntsc/md_ntsc.h @@ -0,0 +1,154 @@ +/* Sega Genesis/Mega Drive NTSC video filter */ + +/* md_ntsc 0.1.2 */ +#ifndef MD_NTSC_H +#define MD_NTSC_H + +#include "md_ntsc_config.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Image parameters, ranging from -1.0 to 1.0. Actual internal values shown +in parenthesis and should remain fairly stable in future versions. */ +typedef struct md_ntsc_setup_t +{ + /* Basic parameters */ + double hue; /* -1 = -180 degrees +1 = +180 degrees */ + double saturation; /* -1 = grayscale (0.0) +1 = oversaturated colors (2.0) */ + double contrast; /* -1 = dark (0.5) +1 = light (1.5) */ + double brightness; /* -1 = dark (0.5) +1 = light (1.5) */ + double sharpness; /* edge contrast enhancement/blurring */ + + /* Advanced parameters */ + double gamma; /* -1 = dark (1.5) +1 = light (0.5) */ + double resolution; /* image resolution */ + double artifacts; /* artifacts caused by color changes */ + double fringing; /* color artifacts caused by brightness changes */ + double bleed; /* color bleed (color resolution reduction) */ + float const* decoder_matrix; /* optional RGB decoder matrix, 6 elements */ + + unsigned char* palette_out; /* optional RGB palette out, 3 bytes per color */ +} md_ntsc_setup_t; + +/* Video format presets */ +extern md_ntsc_setup_t const md_ntsc_composite; /* color bleeding + artifacts */ +extern md_ntsc_setup_t const md_ntsc_svideo; /* color bleeding only */ +extern md_ntsc_setup_t const md_ntsc_rgb; /* crisp image */ +extern md_ntsc_setup_t const md_ntsc_monochrome;/* desaturated + artifacts */ + +enum { md_ntsc_palette_size = 512 }; + +/* Initializes and adjusts parameters. Can be called multiple times on the same +md_ntsc_t object. Can pass NULL for either parameter. */ +typedef struct md_ntsc_t md_ntsc_t; +void md_ntsc_init( md_ntsc_t* ntsc, md_ntsc_setup_t const* setup ); + +/* Filters one row of pixels. Input pixel format is set by MD_NTSC_IN_FORMAT +and output RGB depth is set by MD_NTSC_OUT_DEPTH. Both default to 16-bit RGB. +In_row_width is the number of pixels to get to the next input row. */ +void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input, + int in_width, int vline); + +/* Number of output pixels written by blitter for given input width. */ +#define MD_NTSC_OUT_WIDTH( in_width ) \ + (((in_width) - 3) / md_ntsc_in_chunk * md_ntsc_out_chunk + md_ntsc_out_chunk) + +/* Number of input pixels that will fit within given output width. Might be +rounded down slightly; use MD_NTSC_OUT_WIDTH() on result to find rounded +value. */ +#define MD_NTSC_IN_WIDTH( out_width ) \ + ((out_width) / md_ntsc_out_chunk * md_ntsc_in_chunk - md_ntsc_in_chunk + 3) + + +/* Interface for user-defined custom blitters */ + +enum { md_ntsc_in_chunk = 4 }; /* number of input pixels read per chunk */ +enum { md_ntsc_out_chunk = 8 }; /* number of output pixels generated per chunk */ +enum { md_ntsc_black = 0 }; /* palette index for black */ + +/* Begin outputting row and start three pixels. First pixel will be cut off a bit. +Declares variables, so must be before first statement in a block (unless you're using C++). */ +#define MD_NTSC_BEGIN_ROW( ntsc, pixel0, pixel1, pixel2, pixel3 ) \ + md_ntsc_rgb_t raw_;\ + unsigned const md_pixel0_ = (pixel0);\ + md_ntsc_rgb_t const* kernel0 = MD_NTSC_IN_FORMAT( ntsc, md_pixel0_ );\ + unsigned const md_pixel1_ = (pixel1);\ + md_ntsc_rgb_t const* kernel1 = MD_NTSC_IN_FORMAT( ntsc, md_pixel1_ );\ + unsigned const md_pixel2_ = (pixel2);\ + md_ntsc_rgb_t const* kernel2 = MD_NTSC_IN_FORMAT( ntsc, md_pixel2_ );\ + unsigned const md_pixel3_ = (pixel3);\ + md_ntsc_rgb_t const* kernel3 = MD_NTSC_IN_FORMAT( ntsc, md_pixel3_ );\ + md_ntsc_rgb_t const* kernelx0;\ + md_ntsc_rgb_t const* kernelx1 = kernel0;\ + md_ntsc_rgb_t const* kernelx2 = kernel0;\ + md_ntsc_rgb_t const* kernelx3 = kernel0 + +/* Begin input pixel */ +#define MD_NTSC_COLOR_IN( index, ntsc, color ) \ + MD_NTSC_COLOR_IN_( index, color, MD_NTSC_IN_FORMAT, ntsc ) + +/* Generate output pixel */ +#define MD_NTSC_RGB_OUT( x, rgb_out ) {\ + raw_ =\ + kernel0 [x+ 0] + kernel1 [(x+6)%8+16] + kernel2 [(x+4)%8 ] + kernel3 [(x+2)%8+16] +\ + kernelx0 [x+ 8] + kernelx1 [(x+6)%8+24] + kernelx2 [(x+4)%8+8] + kernelx3 [(x+2)%8+24];\ + MD_NTSC_CLAMP_( raw_, 0 );\ + MD_NTSC_RGB_OUT_( rgb_out, 0 );\ +} + + +/* private */ +enum { md_ntsc_entry_size = 2 * 16 }; +typedef unsigned long md_ntsc_rgb_t; +struct md_ntsc_t { + md_ntsc_rgb_t table [md_ntsc_palette_size] [md_ntsc_entry_size]; +}; + +#define MD_NTSC_BGR9( ntsc, n ) (ntsc)->table [n & 0x1FF] + +#define MD_NTSC_RGB16( ntsc, n ) \ + (md_ntsc_rgb_t*) ((char*) (ntsc)->table +\ + ((n << 9 & 0x3800) | (n & 0x0700) | (n >> 8 & 0x00E0)) *\ + (md_ntsc_entry_size * sizeof (md_ntsc_rgb_t) / 32)) + +#define MD_NTSC_RGB15( ntsc, n ) \ + (md_ntsc_rgb_t*) ((char*) (ntsc)->table +\ + ((n << 8 & 0x1C00) | (n & 0x0380) | (n >> 8 & 0x0070)) *\ + (md_ntsc_entry_size * sizeof (md_ntsc_rgb_t) / 16)) + +/* common ntsc macros */ +#define md_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1)) +#define md_ntsc_clamp_mask (md_ntsc_rgb_builder * 3 / 2) +#define md_ntsc_clamp_add (md_ntsc_rgb_builder * 0x101) +#define MD_NTSC_CLAMP_( io, shift ) {\ + md_ntsc_rgb_t sub = (io) >> (9-(shift)) & md_ntsc_clamp_mask;\ + md_ntsc_rgb_t clamp = md_ntsc_clamp_add - sub;\ + io |= clamp;\ + clamp -= sub;\ + io &= clamp;\ +} + +#define MD_NTSC_COLOR_IN_( index, color, ENTRY, table ) {\ + unsigned color_;\ + kernelx##index = kernel##index;\ + kernel##index = (color_ = (color), ENTRY( table, color_ ));\ +} + +/* x is always zero except in snes_ntsc library */ +#if MD_NTSC_OUT_DEPTH == 15 +#define MD_NTSC_RGB_OUT_( rgb_out, x ) {\ + rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\ + } +#elif MD_NTSC_OUT_DEPTH == 16 +#define MD_NTSC_RGB_OUT_( rgb_out, x ) {\ + rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\ + } +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/genplus-gx/core/ntsc/md_ntsc_config.h b/genplus-gx/core/ntsc/md_ntsc_config.h new file mode 100644 index 0000000000..8864dde3f5 --- /dev/null +++ b/genplus-gx/core/ntsc/md_ntsc_config.h @@ -0,0 +1,31 @@ +/* Configure library by modifying this file */ + +#ifndef MD_NTSC_CONFIG_H +#define MD_NTSC_CONFIG_H + +/* Format of source & output pixels (RGB555 or RGB565 only)*/ +#ifdef USE_15BPP_RENDERING +#define MD_NTSC_IN_FORMAT MD_NTSC_RGB15 +#define MD_NTSC_OUT_DEPTH 15 +#else +#define MD_NTSC_IN_FORMAT MD_NTSC_RGB16 +#define MD_NTSC_OUT_DEPTH 16 +#endif + +/* Original CRAM format (not used) */ +/* #define MD_NTSC_IN_FORMAT MD_NTSC_BGR9 */ + +/* The following affect the built-in blitter only; a custom blitter can +handle things however it wants. */ + +/* Type of input pixel values (fixed to 16-bit) */ +#define MD_NTSC_IN_T unsigned short + +/* Each raw pixel input value is passed through this. You might want to mask +the pixel index if you use the high bits as flags, etc. */ +#define MD_NTSC_ADJ_IN( in ) in + +/* For each pixel, this is the basic operation: +output_color = MD_NTSC_ADJ_IN( MD_NTSC_IN_T ) */ + +#endif diff --git a/genplus-gx/core/ntsc/md_ntsc_impl.h b/genplus-gx/core/ntsc/md_ntsc_impl.h new file mode 100644 index 0000000000..274fb81c1b --- /dev/null +++ b/genplus-gx/core/ntsc/md_ntsc_impl.h @@ -0,0 +1,439 @@ +/* md_ntsc 0.1.2. http://www.slack.net/~ant/ */ + +/* Common implementation of NTSC filters */ + +#include +#include + +/* Copyright (C) 2006-2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#define DISABLE_CORRECTION 0 + +#undef PI +#define PI 3.14159265358979323846f + +#ifndef LUMA_CUTOFF + #define LUMA_CUTOFF 0.20 +#endif +#ifndef gamma_size + #define gamma_size 1 +#endif +#ifndef rgb_bits + #define rgb_bits 8 +#endif +#ifndef artifacts_max + #define artifacts_max (artifacts_mid * 1.5f) +#endif +#ifndef fringing_max + #define fringing_max (fringing_mid * 2) +#endif +#ifndef STD_HUE_CONDITION + #define STD_HUE_CONDITION( setup ) 1 +#endif + +#define ext_decoder_hue (std_decoder_hue + 15) +#define rgb_unit (1 << rgb_bits) +#define rgb_offset (rgb_unit * 2 + 0.5f) + +enum { burst_size = md_ntsc_entry_size / burst_count }; +enum { kernel_half = 16 }; +enum { kernel_size = kernel_half * 2 + 1 }; + +typedef struct init_t +{ + float to_rgb [burst_count * 6]; + float to_float [gamma_size]; + float contrast; + float brightness; + float artifacts; + float fringing; + float kernel [rescale_out * kernel_size * 2]; +} init_t; + +#define ROTATE_IQ( i, q, sin_b, cos_b ) {\ + float t;\ + t = i * cos_b - q * sin_b;\ + q = i * sin_b + q * cos_b;\ + i = t;\ +} + +static void init_filters( init_t* impl, md_ntsc_setup_t const* setup ) +{ +#if rescale_out > 1 + float kernels [kernel_size * 2]; +#else + float* const kernels = impl->kernel; +#endif + + /* generate luma (y) filter using sinc kernel */ + { + /* sinc with rolloff (dsf) */ + float const rolloff = 1 + (float) setup->sharpness * (float) 0.032; + float const maxh = 32; + float const pow_a_n = (float) pow( rolloff, maxh ); + float sum; + int i; + /* quadratic mapping to reduce negative (blurring) range */ + float to_angle = (float) setup->resolution + 1; + to_angle = PI / maxh * (float) LUMA_CUTOFF * (to_angle * to_angle + 1); + + kernels [kernel_size * 3 / 2] = maxh; /* default center value */ + for ( i = 0; i < kernel_half * 2 + 1; i++ ) + { + int x = i - kernel_half; + float angle = x * to_angle; + /* instability occurs at center point with rolloff very close to 1.0 */ + if ( x || pow_a_n > (float) 1.056 || pow_a_n < (float) 0.981 ) + { + float rolloff_cos_a = rolloff * (float) cos( angle ); + float num = 1 - rolloff_cos_a - + pow_a_n * (float) cos( maxh * angle ) + + pow_a_n * rolloff * (float) cos( (maxh - 1) * angle ); + float den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff; + float dsf = num / den; + kernels [kernel_size * 3 / 2 - kernel_half + i] = dsf - (float) 0.5; + } + } + + /* apply blackman window and find sum */ + sum = 0; + for ( i = 0; i < kernel_half * 2 + 1; i++ ) + { + float x = PI * 2 / (kernel_half * 2) * i; + float blackman = 0.42f - 0.5f * (float) cos( x ) + 0.08f * (float) cos( x * 2 ); + sum += (kernels [kernel_size * 3 / 2 - kernel_half + i] *= blackman); + } + + /* normalize kernel */ + sum = 1.0f / sum; + for ( i = 0; i < kernel_half * 2 + 1; i++ ) + { + int x = kernel_size * 3 / 2 - kernel_half + i; + kernels [x] *= sum; + assert( kernels [x] == kernels [x] ); /* catch numerical instability */ + } + } + + /* generate chroma (iq) filter using gaussian kernel */ + { + float const cutoff_factor = -0.03125f; + float cutoff = (float) setup->bleed; + int i; + + if ( cutoff < 0 ) + { + /* keep extreme value accessible only near upper end of scale (1.0) */ + cutoff *= cutoff; + cutoff *= cutoff; + cutoff *= cutoff; + cutoff *= -30.0f / 0.65f; + } + cutoff = cutoff_factor - 0.65f * cutoff_factor * cutoff; + + for ( i = -kernel_half; i <= kernel_half; i++ ) + kernels [kernel_size / 2 + i] = (float) exp( i * i * cutoff ); + + /* normalize even and odd phases separately */ + for ( i = 0; i < 2; i++ ) + { + float sum = 0; + int x; + for ( x = i; x < kernel_size; x += 2 ) + sum += kernels [x]; + + sum = 1.0f / sum; + for ( x = i; x < kernel_size; x += 2 ) + { + kernels [x] *= sum; + assert( kernels [x] == kernels [x] ); /* catch numerical instability */ + } + } + } + + /* + printf( "luma:\n" ); + for ( i = kernel_size; i < kernel_size * 2; i++ ) + printf( "%f\n", kernels [i] ); + printf( "chroma:\n" ); + for ( i = 0; i < kernel_size; i++ ) + printf( "%f\n", kernels [i] ); + */ + + /* generate linear rescale kernels */ + #if rescale_out > 1 + { + float weight = 1.0f; + float* out = impl->kernel; + int n = rescale_out; + do + { + float remain = 0; + int i; + weight -= 1.0f / rescale_in; + for ( i = 0; i < kernel_size * 2; i++ ) + { + float cur = kernels [i]; + float m = cur * weight; + *out++ = m + remain; + remain = cur - m; + } + } + while ( --n ); + } + #endif +} + +static float const default_decoder [6] = + { 0.956f, 0.621f, -0.272f, -0.647f, -1.105f, 1.702f }; + +static void init( init_t* impl, md_ntsc_setup_t const* setup ) +{ + impl->brightness = (float) setup->brightness * (0.5f * rgb_unit) + rgb_offset; + impl->contrast = (float) setup->contrast * (0.5f * rgb_unit) + rgb_unit; + #ifdef default_palette_contrast + if ( !setup->palette ) + impl->contrast *= default_palette_contrast; + #endif + + impl->artifacts = (float) setup->artifacts; + if ( impl->artifacts > 0 ) + impl->artifacts *= artifacts_max - artifacts_mid; + impl->artifacts = impl->artifacts * artifacts_mid + artifacts_mid; + + impl->fringing = (float) setup->fringing; + if ( impl->fringing > 0 ) + impl->fringing *= fringing_max - fringing_mid; + impl->fringing = impl->fringing * fringing_mid + fringing_mid; + + init_filters( impl, setup ); + + /* generate gamma table */ + if ( gamma_size > 1 ) + { + float const to_float = 1.0f / (gamma_size - (gamma_size > 1)); + float const gamma = 1.1333f - (float) setup->gamma * 0.5f; + /* match common PC's 2.2 gamma to TV's 2.65 gamma */ + int i; + for ( i = 0; i < gamma_size; i++ ) + impl->to_float [i] = + (float) pow( i * to_float, gamma ) * impl->contrast + impl->brightness; + } + + /* setup decoder matricies */ + { + float hue = (float) setup->hue * PI + PI / 180 * ext_decoder_hue; + float sat = (float) setup->saturation + 1; + float const* decoder = setup->decoder_matrix; + if ( !decoder ) + { + decoder = default_decoder; + if ( STD_HUE_CONDITION( setup ) ) + hue += PI / 180 * (std_decoder_hue - ext_decoder_hue); + } + + { + float s = (float) sin( hue ) * sat; + float c = (float) cos( hue ) * sat; + float* out = impl->to_rgb; + int n; + + n = burst_count; + do + { + float const* in = decoder; + int n = 3; + do + { + float i = *in++; + float q = *in++; + *out++ = i * c - q * s; + *out++ = i * s + q * c; + } + while ( --n ); + if ( burst_count <= 1 ) + break; + ROTATE_IQ( s, c, 0.866025f, -0.5f ); /* +120 degrees */ + } + while ( --n ); + } + } +} + +/* kernel generation */ + +#define RGB_TO_YIQ( r, g, b, y, i ) (\ + (y = (r) * 0.299f + (g) * 0.587f + (b) * 0.114f),\ + (i = (r) * 0.596f - (g) * 0.275f - (b) * 0.321f),\ + ((r) * 0.212f - (g) * 0.523f + (b) * 0.311f)\ +) + +#define YIQ_TO_RGB( y, i, q, to_rgb, type, r, g ) (\ + r = (type) (y + to_rgb [0] * i + to_rgb [1] * q),\ + g = (type) (y + to_rgb [2] * i + to_rgb [3] * q),\ + (type) (y + to_rgb [4] * i + to_rgb [5] * q)\ +) + +#define PACK_RGB( r, g, b ) ((r) << 21 | (g) << 11 | (b) << 1) + +enum { rgb_kernel_size = burst_size / alignment_count }; +enum { rgb_bias = rgb_unit * 2 * md_ntsc_rgb_builder }; + +typedef struct pixel_info_t +{ + int offset; + float negate; + float kernel [4]; +} pixel_info_t; + +#if rescale_in > 1 + #define PIXEL_OFFSET_( ntsc, scaled ) \ + (kernel_size / 2 + ntsc + (scaled != 0) + (rescale_out - scaled) % rescale_out + \ + (kernel_size * 2 * scaled)) + + #define PIXEL_OFFSET( ntsc, scaled ) \ + PIXEL_OFFSET_( ((ntsc) - (scaled) / rescale_out * rescale_in),\ + (((scaled) + rescale_out * 10) % rescale_out) ),\ + (1.0f - (((ntsc) + 100) & 2)) +#else + #define PIXEL_OFFSET( ntsc, scaled ) \ + (kernel_size / 2 + (ntsc) - (scaled)),\ + (1.0f - (((ntsc) + 100) & 2)) +#endif + +extern pixel_info_t const md_ntsc_pixels [alignment_count]; + +/* Generate pixel at all burst phases and column alignments */ +static void gen_kernel( init_t* impl, float y, float i, float q, md_ntsc_rgb_t* out ) +{ + /* generate for each scanline burst phase */ + float const* to_rgb = impl->to_rgb; + int burst_remain = burst_count; + y -= rgb_offset; + do + { + /* Encode yiq into *two* composite signals (to allow control over artifacting). + Convolve these with kernels which: filter respective components, apply + sharpening, and rescale horizontally. Convert resulting yiq to rgb and pack + into integer. Based on algorithm by NewRisingSun. */ + pixel_info_t const* pixel = md_ntsc_pixels; + int alignment_remain = alignment_count; + do + { + /* negate is -1 when composite starts at odd multiple of 2 */ + float const yy = y * impl->fringing * pixel->negate; + float const ic0 = (i + yy) * pixel->kernel [0]; + float const qc1 = (q + yy) * pixel->kernel [1]; + float const ic2 = (i - yy) * pixel->kernel [2]; + float const qc3 = (q - yy) * pixel->kernel [3]; + + float const factor = impl->artifacts * pixel->negate; + float const ii = i * factor; + float const yc0 = (y + ii) * pixel->kernel [0]; + float const yc2 = (y - ii) * pixel->kernel [2]; + + float const qq = q * factor; + float const yc1 = (y + qq) * pixel->kernel [1]; + float const yc3 = (y - qq) * pixel->kernel [3]; + + float const* k = &impl->kernel [pixel->offset]; + int n; + ++pixel; + for ( n = rgb_kernel_size; n; --n ) + { + float i = k[0]*ic0 + k[2]*ic2; + float q = k[1]*qc1 + k[3]*qc3; + float y = k[kernel_size+0]*yc0 + k[kernel_size+1]*yc1 + + k[kernel_size+2]*yc2 + k[kernel_size+3]*yc3 + rgb_offset; + if ( rescale_out <= 1 ) + k--; + else if ( k < &impl->kernel [kernel_size * 2 * (rescale_out - 1)] ) + k += kernel_size * 2 - 1; + else + k -= kernel_size * 2 * (rescale_out - 1) + 2; + { + int r, g, b = YIQ_TO_RGB( y, i, q, to_rgb, int, r, g ); + *out++ = PACK_RGB( r, g, b ) - rgb_bias; + } + } + } + while ( alignment_count > 1 && --alignment_remain ); + + if ( burst_count <= 1 ) + break; + + to_rgb += 6; + + ROTATE_IQ( i, q, -0.866025f, -0.5f ); /* -120 degrees */ + } + while ( --burst_remain ); +} + +static void correct_errors( md_ntsc_rgb_t color, md_ntsc_rgb_t* out ); + +#if DISABLE_CORRECTION + #define CORRECT_ERROR( a ) { out [i] += rgb_bias; } + #define DISTRIBUTE_ERROR( a, b, c ) { out [i] += rgb_bias; } +#else + #define CORRECT_ERROR( a ) { out [a] += error; } + #define DISTRIBUTE_ERROR( a, b, c ) {\ + md_ntsc_rgb_t fourth = (error + 2 * md_ntsc_rgb_builder) >> 2;\ + fourth &= (rgb_bias >> 1) - md_ntsc_rgb_builder;\ + fourth -= rgb_bias >> 2;\ + out [a] += fourth;\ + out [b] += fourth;\ + out [c] += fourth;\ + out [i] += error - (fourth * 3);\ + } +#endif + +#define RGB_PALETTE_OUT( rgb, out_ )\ +{\ + unsigned char* out = (out_);\ + md_ntsc_rgb_t clamped = (rgb);\ + MD_NTSC_CLAMP_( clamped, (8 - rgb_bits) );\ + out [0] = (unsigned char) (clamped >> 21);\ + out [1] = (unsigned char) (clamped >> 11);\ + out [2] = (unsigned char) (clamped >> 1);\ +} + +/* blitter related */ + +#ifndef restrict + #if defined (__GNUC__) + #define restrict __restrict__ + #elif defined (_MSC_VER) && _MSC_VER > 1300 + #define restrict + #else + /* no support for restricted pointers */ + #define restrict + #endif +#endif + +#include + +#if MD_NTSC_OUT_DEPTH <= 16 + #if USHRT_MAX == 0xFFFF + typedef unsigned short md_ntsc_out_t; + #else + #error "Need 16-bit int type" + #endif + +#else + #if UINT_MAX == 0xFFFFFFFF + typedef unsigned int md_ntsc_out_t; + #elif ULONG_MAX == 0xFFFFFFFF + typedef unsigned long md_ntsc_out_t; + #else + #error "Need 32-bit int type" + #endif + +#endif diff --git a/genplus-gx/core/ntsc/readme.txt b/genplus-gx/core/ntsc/readme.txt new file mode 100644 index 0000000000..152daa04e4 --- /dev/null +++ b/genplus-gx/core/ntsc/readme.txt @@ -0,0 +1,58 @@ +sms_ntsc 0.2.3: Sega Master System NTSC Video Filter +---------------------------------------------------- +This library filters a Sega Master System image to match what a TV would +show, allowing an authentic image in an emulator. It uses a highly +optimized algorithm to perform the same signal processing as an NTSC +decoder in a TV, giving very similar pixel artifacts and color bleeding. +The usual picture controls can be adjusted: hue, saturation, contrast, +brightness, and sharpness. Additionally, the amount of NTSC chroma and +luma artifacts can be reduced, allowing an image that corresponds to +composite video (artifacts), S-video (color bleeding only), RGB (clean +pixels), or anywhere inbetween. + +The output is scaled to the proper horizontal width, leaving it up the +emulator to simply double the height. Specialized blitters can be easily +written using a special interface, allowing customization of input and +output pixel formats, optimization for the host platform, and efficient +scanline doubling. + +Blitting a 248x192 source image to a 581x384 pixel 16-bit RGB memory +buffer at 60 frames per second uses 7% CPU on a 2.0 GHz Athlon 3500+ and +33% CPU on a 10-year-old 400 MHz G3 PowerMac. + +Author : Shay Green +Website : http://www.slack.net/~ant/ +Forum : http://groups.google.com/group/blargg-sound-libs +License : GNU Lesser General Public License (LGPL) +Language: C or C++ + + +Getting Started +--------------- +Build a program from demo.c, sms_ntsc.c, and the SDL multimedia library +(see http://libsdl.org/). Run it with "test.bmp" in the same directory +and it should show the filtered image. See demo.c for more. + +See sms_ntsc.txt for documentation and sms_ntsc.h for reference. Post to +the discussion forum for assistance. + + +Files +----- +readme.txt Essential information +sms_ntsc.txt Library documentation +changes.txt Changes made since previous releases +license.txt GNU Lesser General Public License + +benchmark.c Measures frame rate and processor usage of library +demo.c Displays and saves NTSC filtered image +demo_impl.h Internal routines used by demo +test.bmp Test image for demo + +sms_ntsc_config.h Library configuration (modify as needed) +sms_ntsc.h Library header and source +sms_ntsc.c +sms_ntsc_impl.h + +-- +Shay Green diff --git a/genplus-gx/core/ntsc/sms_ntsc.c b/genplus-gx/core/ntsc/sms_ntsc.c new file mode 100644 index 0000000000..d41239e342 --- /dev/null +++ b/genplus-gx/core/ntsc/sms_ntsc.c @@ -0,0 +1,141 @@ +/* sms_ntsc 0.2.3. http://www.slack.net/~ant/ */ + +/* Modified for use with Genesis Plus GX -- EkeEke */ + +#include "shared.h" +#include "sms_ntsc.h" + +/* Copyright (C) 2006-2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +sms_ntsc_setup_t const sms_ntsc_monochrome = { 0,-1, 0, 0,.2, 0, .2,-.2,-.2,-1, 0, 0 }; +sms_ntsc_setup_t const sms_ntsc_composite = { 0, 0, 0, 0, 0, 0,.25, 0, 0, 0, 0, 0 }; +sms_ntsc_setup_t const sms_ntsc_svideo = { 0, 0, 0, 0, 0, 0,.25, -1, -1, 0, 0, 0 }; +sms_ntsc_setup_t const sms_ntsc_rgb = { 0, 0, 0, 0,.2, 0,.70, -1, -1,-1, 0, 0 }; + +#define alignment_count 3 +#define burst_count 1 +#define rescale_in 8 +#define rescale_out 7 + +#define artifacts_mid 0.4f +#define artifacts_max 1.2f +#define fringing_mid 0.8f +#define std_decoder_hue 0 + +#define gamma_size 16 + +#include "sms_ntsc_impl.h" + +/* 3 input pixels -> 8 composite samples */ +pixel_info_t const sms_ntsc_pixels [alignment_count] = { + { PIXEL_OFFSET( -4, -9 ), { 1, 1, .6667f, 0 } }, + { PIXEL_OFFSET( -2, -7 ), { .3333f, 1, 1, .3333f } }, + { PIXEL_OFFSET( 0, -5 ), { 0, .6667f, 1, 1 } }, +}; + +static void correct_errors( sms_ntsc_rgb_t color, sms_ntsc_rgb_t* out ) +{ + unsigned i; + for ( i = 0; i < rgb_kernel_size / 2; i++ ) + { + sms_ntsc_rgb_t error = color - + out [i ] - out [(i+12)%14+14] - out [(i+10)%14+28] - + out [i + 7] - out [i + 5 +14] - out [i + 3 +28]; + CORRECT_ERROR( i + 3 + 28 ); + } +} + +void sms_ntsc_init( sms_ntsc_t* ntsc, sms_ntsc_setup_t const* setup ) +{ + int entry; + init_t impl; + if ( !setup ) + setup = &sms_ntsc_composite; + init( &impl, setup ); + + for ( entry = 0; entry < sms_ntsc_palette_size; entry++ ) + { + float bb = impl.to_float [entry >> 8 & 0x0F]; + float gg = impl.to_float [entry >> 4 & 0x0F]; + float rr = impl.to_float [entry & 0x0F]; + + float y, i, q = RGB_TO_YIQ( rr, gg, bb, y, i ); + + int r, g, b = YIQ_TO_RGB( y, i, q, impl.to_rgb, int, r, g ); + sms_ntsc_rgb_t rgb = PACK_RGB( r, g, b ); + + if ( setup->palette_out ) + RGB_PALETTE_OUT( rgb, &setup->palette_out [entry * 3] ); + + if ( ntsc ) + { + gen_kernel( &impl, y, i, q, ntsc->table [entry] ); + correct_errors( rgb, ntsc->table [entry] ); + } + } +} + +#ifndef CUSTOM_BLITTER +void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input, + int in_width, int vline) +{ + int const chunk_count = in_width / sms_ntsc_in_chunk; + + /* handle extra 0, 1, or 2 pixels by placing them at beginning of row */ + int const in_extra = in_width - chunk_count * sms_ntsc_in_chunk; + unsigned const extra2 = (unsigned) -(in_extra >> 1 & 1); /* (unsigned) -1 = ~0 */ + unsigned const extra1 = (unsigned) -(in_extra & 1) | extra2; + + /* use palette entry 0 for unused pixels */ + SMS_NTSC_IN_T border = table[0]; + + SMS_NTSC_BEGIN_ROW( ntsc, border, + (SMS_NTSC_ADJ_IN( table[input[0]] )) & extra2, + (SMS_NTSC_ADJ_IN( table[input[extra2 & 1]] )) & extra1 ); + + sms_ntsc_out_t* restrict line_out = (sms_ntsc_out_t*)(&bitmap.data[(vline * bitmap.pitch)]); + + int n; + input += in_extra; + + for ( n = chunk_count; n; --n ) + { + /* order of input and output pixels must not be altered */ + SMS_NTSC_COLOR_IN( 0, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) ); + SMS_NTSC_RGB_OUT( 0, *line_out++ ); + SMS_NTSC_RGB_OUT( 1, *line_out++ ); + + SMS_NTSC_COLOR_IN( 1, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) ); + SMS_NTSC_RGB_OUT( 2, *line_out++ ); + SMS_NTSC_RGB_OUT( 3, *line_out++ ); + + SMS_NTSC_COLOR_IN( 2, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) ); + SMS_NTSC_RGB_OUT( 4, *line_out++ ); + SMS_NTSC_RGB_OUT( 5, *line_out++ ); + SMS_NTSC_RGB_OUT( 6, *line_out++ ); + } + + /* finish final pixels */ + SMS_NTSC_COLOR_IN( 0, ntsc, border ); + SMS_NTSC_RGB_OUT( 0, *line_out++ ); + SMS_NTSC_RGB_OUT( 1, *line_out++ ); + + SMS_NTSC_COLOR_IN( 1, ntsc, border ); + SMS_NTSC_RGB_OUT( 2, *line_out++ ); + SMS_NTSC_RGB_OUT( 3, *line_out++ ); + + SMS_NTSC_COLOR_IN( 2, ntsc, border ); + SMS_NTSC_RGB_OUT( 4, *line_out++ ); + SMS_NTSC_RGB_OUT( 5, *line_out++ ); + SMS_NTSC_RGB_OUT( 6, *line_out++ ); +} +#endif diff --git a/genplus-gx/core/ntsc/sms_ntsc.h b/genplus-gx/core/ntsc/sms_ntsc.h new file mode 100644 index 0000000000..7546fa35ec --- /dev/null +++ b/genplus-gx/core/ntsc/sms_ntsc.h @@ -0,0 +1,154 @@ +/* Sega Master System/Game Gear/TI 99/4A NTSC video filter */ + +/* sms_ntsc 0.2.3 */ +#ifndef SMS_NTSC_H +#define SMS_NTSC_H + +#include "sms_ntsc_config.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Image parameters, ranging from -1.0 to 1.0. Actual internal values shown +in parenthesis and should remain fairly stable in future versions. */ +typedef struct sms_ntsc_setup_t +{ + /* Basic parameters */ + double hue; /* -1 = -180 degrees +1 = +180 degrees */ + double saturation; /* -1 = grayscale (0.0) +1 = oversaturated colors (2.0) */ + double contrast; /* -1 = dark (0.5) +1 = light (1.5) */ + double brightness; /* -1 = dark (0.5) +1 = light (1.5) */ + double sharpness; /* edge contrast enhancement/blurring */ + + /* Advanced parameters */ + double gamma; /* -1 = dark (1.5) +1 = light (0.5) */ + double resolution; /* image resolution */ + double artifacts; /* artifacts caused by color changes */ + double fringing; /* color artifacts caused by brightness changes */ + double bleed; /* color bleed (color resolution reduction) */ + float const* decoder_matrix; /* optional RGB decoder matrix, 6 elements */ + + unsigned char* palette_out; /* optional RGB palette out, 3 bytes per color */ +} sms_ntsc_setup_t; + +/* Video format presets */ +extern sms_ntsc_setup_t const sms_ntsc_composite; /* color bleeding + artifacts */ +extern sms_ntsc_setup_t const sms_ntsc_svideo; /* color bleeding only */ +extern sms_ntsc_setup_t const sms_ntsc_rgb; /* crisp image */ +extern sms_ntsc_setup_t const sms_ntsc_monochrome;/* desaturated + artifacts */ + +enum { sms_ntsc_palette_size = 4096 }; + +/* Initializes and adjusts parameters. Can be called multiple times on the same +sms_ntsc_t object. Can pass NULL for either parameter. */ +typedef struct sms_ntsc_t sms_ntsc_t; +void sms_ntsc_init( sms_ntsc_t* ntsc, sms_ntsc_setup_t const* setup ); + +/* Filters one row of pixels. Input pixel format is set by SMS_NTSC_IN_FORMAT +and output RGB depth is set by SMS_NTSC_OUT_DEPTH. Both default to 16-bit RGB. +In_row_width is the number of pixels to get to the next input row. */ +void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input, + int in_width, int vline); + +/* Number of output pixels written by blitter for given input width. */ +#define SMS_NTSC_OUT_WIDTH( in_width ) \ + (((in_width) / sms_ntsc_in_chunk + 1) * sms_ntsc_out_chunk) + +/* Number of input pixels that will fit within given output width. Might be +rounded down slightly; use SMS_NTSC_OUT_WIDTH() on result to find rounded +value. */ +#define SMS_NTSC_IN_WIDTH( out_width ) \ + (((out_width) / sms_ntsc_out_chunk - 1) * sms_ntsc_in_chunk + 2) + + +/* Interface for user-defined custom blitters */ + +enum { sms_ntsc_in_chunk = 3 }; /* number of input pixels read per chunk */ +enum { sms_ntsc_out_chunk = 7 }; /* number of output pixels generated per chunk */ + +/* Begins outputting row and starts three pixels. First pixel will be cut off a bit. +Declares variables, so must be before first statement in a block (unless you're using C++). */ +#define SMS_NTSC_BEGIN_ROW( ntsc, pixel0, pixel1, pixel2 ) \ + SMS_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, SMS_NTSC_IN_FORMAT, ntsc ) + +/* Begins input pixel */ +#define SMS_NTSC_COLOR_IN( in_index, ntsc, color_in ) \ + SMS_NTSC_COLOR_IN_( in_index, color_in, SMS_NTSC_IN_FORMAT, ntsc ) + +/* Generates output pixel */ +#define SMS_NTSC_RGB_OUT( x, rgb_out ) {\ + raw_ =\ + kernel0 [x ] + kernel1 [(x+12)%7+14] + kernel2 [(x+10)%7+28] +\ + kernelx0 [(x+7)%14] + kernelx1 [(x+ 5)%7+21] + kernelx2 [(x+ 3)%7+35];\ + SMS_NTSC_CLAMP_( raw_, 0 );\ + SMS_NTSC_RGB_OUT_( rgb_out, 0 );\ +} + +/* private */ +enum { sms_ntsc_entry_size = 3 * 14 }; +typedef unsigned long sms_ntsc_rgb_t; +struct sms_ntsc_t { + sms_ntsc_rgb_t table [sms_ntsc_palette_size] [sms_ntsc_entry_size]; +}; + +#define SMS_NTSC_BGR12( ntsc, n ) (ntsc)->table [n & 0xFFF] + +#define SMS_NTSC_RGB16( ntsc, n ) \ + (sms_ntsc_rgb_t const*) ((char const*) (ntsc)->table +\ + ((n << 10 & 0x7800) | (n & 0x0780) | (n >> 9 & 0x0078)) *\ + (sms_ntsc_entry_size * sizeof (sms_ntsc_rgb_t) / 8)) + +#define SMS_NTSC_RGB15( ntsc, n ) \ + (sms_ntsc_rgb_t const*) ((char const*) (ntsc)->table +\ + ((n << 9 & 0x3C00) | (n & 0x03C0) | (n >> 9 & 0x003C)) *\ + (sms_ntsc_entry_size * sizeof (sms_ntsc_rgb_t) / 4)) + +/* common 3->7 ntsc macros */ +#define SMS_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, ENTRY, table ) \ + sms_ntsc_rgb_t raw_;\ + unsigned const sms_ntsc_pixel0_ = (pixel0);\ + sms_ntsc_rgb_t const* kernel0 = ENTRY( table, sms_ntsc_pixel0_ );\ + unsigned const sms_ntsc_pixel1_ = (pixel1);\ + sms_ntsc_rgb_t const* kernel1 = ENTRY( table, sms_ntsc_pixel1_ );\ + unsigned const sms_ntsc_pixel2_ = (pixel2);\ + sms_ntsc_rgb_t const* kernel2 = ENTRY( table, sms_ntsc_pixel2_ );\ + sms_ntsc_rgb_t const* kernelx0;\ + sms_ntsc_rgb_t const* kernelx1 = kernel0;\ + sms_ntsc_rgb_t const* kernelx2 = kernel0 + + +/* common ntsc macros */ +#define sms_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1)) +#define sms_ntsc_clamp_mask (sms_ntsc_rgb_builder * 3 / 2) +#define sms_ntsc_clamp_add (sms_ntsc_rgb_builder * 0x101) +#define SMS_NTSC_CLAMP_( io, shift ) {\ + sms_ntsc_rgb_t sub = (io) >> (9-(shift)) & sms_ntsc_clamp_mask;\ + sms_ntsc_rgb_t clamp = sms_ntsc_clamp_add - sub;\ + io |= clamp;\ + clamp -= sub;\ + io &= clamp;\ +} + +#define SMS_NTSC_COLOR_IN_( index, color, ENTRY, table ) {\ + unsigned color_;\ + kernelx##index = kernel##index;\ + kernel##index = (color_ = (color), ENTRY( table, color_ ));\ +} + +/* x is always zero except in snes_ntsc library */ +#if SMS_NTSC_OUT_DEPTH == 15 +#define SMS_NTSC_RGB_OUT_( rgb_out, x ) {\ + rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\ + } +#elif SMS_NTSC_OUT_DEPTH == 16 +#define SMS_NTSC_RGB_OUT_( rgb_out, x) {\ + rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\ + } +#endif + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/genplus-gx/core/ntsc/sms_ntsc.txt b/genplus-gx/core/ntsc/sms_ntsc.txt new file mode 100644 index 0000000000..21b010b099 --- /dev/null +++ b/genplus-gx/core/ntsc/sms_ntsc.txt @@ -0,0 +1,119 @@ +sms_ntsc 0.2.3: Sega Master System NTSC Video Filter +---------------------------------------------------- +Author : Shay Green +Website : http://www.slack.net/~ant/ +Forum : http://groups.google.com/group/blargg-sound-libs +License : GNU Lesser General Public License (LGPL) +Language: C or C++ + + +Overview +-------- +To perform NTSC filtering, first allocate memory for a sms_ntsc_t object +and call sms_ntsc_init(), then call sms_ntsc_blit() to perform +filtering. You can call sms_ntsc_init() at any time to change image +parameters. + +By default, sms_ntsc_blit() reads and writes pixels in 16-bit RGB. Edit +sms_ntsc_config.h to change this. + + +RGB Palette Generation +---------------------- +A 4096-color RGB palette can be generated for use in a normal blitter. +In your sms_ntsc_setup_t structure, point palette_out to a 12288-byte +buffer (4096 * 3) to hold the palette, then call sms_ntsc_init(). If you +only need the palette and aren't going to be using the NTSC blitter, +pass 0 for the first parameter. + + +Image Parameters +---------------- +Many image parameters can be adjusted and presets are provided for +composite video, S-video, RGB, and monochrome. Most are floating-point +values with a general range of -1.0 to 1.0, where 0 is normal. The +ranges are adjusted so that one parameter at an extreme (-1 or +1) and +the rest at zero shouldn't result in any internal overflow (garbage +pixels). Setting multiple parameters to their extreme can produce +garbage. Put another way, the state space defined by all parameters +within the range -1 to +1 is not fully usable, but some extreme corners +are very useful so I don't want to reduce the parameter ranges. + +The sharpness and resolution parameters have similar effects. Resolution +affects how crisp pixels are. Sharpness merely enhances the edges by +increasing contrast, which makes things brighter at the edges. Artifacts +sets how much "junk" is around the edges where colors and brightness +change in the image, where -1 completely eliminates them. (Color) bleed +affects how much colors blend together and the artifact colors at the +edges of pixels surrounded by black. (Color) fringing affects how much +color fringing occurs around the edges of bright objects, especially +white text on a black background. + +When using custom settings, initialize your sms_ntsc_setup_t using one +of the standard setups before customizing it. This will ensure that all +fields are properly initialized, including any added in future releases +of the library that your current code can't even know about. + + sms_ntsc_setup_t setup; + setup = sms_ntsc_composite; /* do this first */ + setup.sharpness = custom_sharpness; + sms_ntsc_init( ntsc, &setup ); + + +Image Size +---------- +For proper aspect ratio, the image generated by the library must be +doubled vertically. + +Use the SMS_NTSC_OUT_WIDTH() and SMS_NTSC_IN_WIDTH() macros to convert +between input and output widths that the blitter uses. For example, if +you are blitting an image 256 pixels wide, use SMS_NTSC_OUT_WIDTH( 256 ) +to find out how many output pixels are written per row. Another example, +use SMS_NTSC_IN_WIDTH( 640 ) to find how many input pixels will fit +within 640 output pixels. + + +Custom Blitter +-------------- +You can write your own blitter, allowing customization of how input +pixels are obtained, the format of output pixels (15, 16, or 32-bit +RGB), optimizations for your platform, and additional effects like +efficient scanline doubling during blitting. + +Macros are included in sms_ntsc.h for writing your blitter so that your +code can be carried over without changes to improved versions of the +library. The default blitter at the end of sms_ntsc.c shows how to use +the macros. Contact me for further assistance. + +The SMS_NTSC_BEGIN_ROW macro allows starting up to three pixels. The +first pixel is cut off; its use is in specifying a background color +other than black for the sliver on the left edge. The next two pixels +can be used to handle the extra one or two pixels not handled by the +main chunks of three pixels. For example if you want to blit 257 input +pixels on a row (for whatever odd reason), you would start the first two +with SMS_NTSC_BEGIN_ROW( ... sms_ntsc_black, line_in [0], line_in [1] ), +then do the remaining 255 in chunks of three (255 is divisible by 3). + + +Limitations +----------- +The library's horizontal rescaling is too wide by about 3% in order to +allow a much more optimal implementation. This means that a 248 pixel +wide input image should appear as 563 output pixels, but with this +library appears as 581 output pixels. TV aspect ratios probably vary by +this much anyway. If you really need unscaled output, contact me and +I'll see about adding it. + + +Thanks +------ +Thanks to NewRisingSun for his original code and explanations of NTSC, +which was a starting point for me learning about NTSC video and +decoding. Thanks to the Nesdev forum for feedback and encouragement. +Thanks to Martin Freij (Nestopia author) and Charles MacDonald (SMS Plus +author) for significant ongoing testing and feedback as the library has +improved. Thanks to byuu (bsnes author) and pagefault (ZSNES team) for +feedback about the SNES version. + +-- +Shay Green diff --git a/genplus-gx/core/ntsc/sms_ntsc_config.h b/genplus-gx/core/ntsc/sms_ntsc_config.h new file mode 100644 index 0000000000..6b9e0bff13 --- /dev/null +++ b/genplus-gx/core/ntsc/sms_ntsc_config.h @@ -0,0 +1,31 @@ +/* Configure library by modifying this file */ + +#ifndef SMS_NTSC_CONFIG_H +#define SMS_NTSC_CONFIG_H + +/* Format of source & output pixels (RGB555 or RGB565 only) */ +#ifdef USE_15BPP_RENDERING +#define SMS_NTSC_IN_FORMAT SMS_NTSC_RGB15 +#define SMS_NTSC_OUT_DEPTH 15 +#else +#define SMS_NTSC_IN_FORMAT SMS_NTSC_RGB16 +#define SMS_NTSC_OUT_DEPTH 16 +#endif + +/* Original CRAM format (not used) */ +/* #define SMS_NTSC_IN_FORMAT SMS_NTSC_BGR12 */ + +/* The following affect the built-in blitter only; a custom blitter can +handle things however it wants. */ + +/* Type of input pixel values (fixed to 16-bit)*/ +#define SMS_NTSC_IN_T unsigned short + +/* Each raw pixel input value is passed through this. You might want to mask +the pixel index if you use the high bits as flags, etc. */ +#define SMS_NTSC_ADJ_IN( in ) in + +/* For each pixel, this is the basic operation: +output_color = SMS_NTSC_ADJ_IN( SMS_NTSC_IN_T ) */ + +#endif diff --git a/genplus-gx/core/ntsc/sms_ntsc_impl.h b/genplus-gx/core/ntsc/sms_ntsc_impl.h new file mode 100644 index 0000000000..cf86a55220 --- /dev/null +++ b/genplus-gx/core/ntsc/sms_ntsc_impl.h @@ -0,0 +1,439 @@ +/* sms_ntsc 0.2.3. http://www.slack.net/~ant/ */ + +/* Common implementation of NTSC filters */ + +#include +#include + +/* Copyright (C) 2006 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#define DISABLE_CORRECTION 0 + +#undef PI +#define PI 3.14159265358979323846f + +#ifndef LUMA_CUTOFF + #define LUMA_CUTOFF 0.20 +#endif +#ifndef gamma_size + #define gamma_size 1 +#endif +#ifndef rgb_bits + #define rgb_bits 8 +#endif +#ifndef artifacts_max + #define artifacts_max (artifacts_mid * 1.5f) +#endif +#ifndef fringing_max + #define fringing_max (fringing_mid * 2) +#endif +#ifndef STD_HUE_CONDITION + #define STD_HUE_CONDITION( setup ) 1 +#endif + +#define ext_decoder_hue (std_decoder_hue + 15) +#define rgb_unit (1 << rgb_bits) +#define rgb_offset (rgb_unit * 2 + 0.5f) + +enum { burst_size = sms_ntsc_entry_size / burst_count }; +enum { kernel_half = 16 }; +enum { kernel_size = kernel_half * 2 + 1 }; + +typedef struct init_t +{ + float to_rgb [burst_count * 6]; + float to_float [gamma_size]; + float contrast; + float brightness; + float artifacts; + float fringing; + float kernel [rescale_out * kernel_size * 2]; +} init_t; + +#define ROTATE_IQ( i, q, sin_b, cos_b ) {\ + float t;\ + t = i * cos_b - q * sin_b;\ + q = i * sin_b + q * cos_b;\ + i = t;\ +} + +static void init_filters( init_t* impl, sms_ntsc_setup_t const* setup ) +{ +#if rescale_out > 1 + float kernels [kernel_size * 2]; +#else + float* const kernels = impl->kernel; +#endif + + /* generate luma (y) filter using sinc kernel */ + { + /* sinc with rolloff (dsf) */ + float const rolloff = 1 + (float) setup->sharpness * (float) 0.032; + float const maxh = 32; + float const pow_a_n = (float) pow( rolloff, maxh ); + float sum; + int i; + /* quadratic mapping to reduce negative (blurring) range */ + float to_angle = (float) setup->resolution + 1; + to_angle = PI / maxh * (float) LUMA_CUTOFF * (to_angle * to_angle + 1); + + kernels [kernel_size * 3 / 2] = maxh; /* default center value */ + for ( i = 0; i < kernel_half * 2 + 1; i++ ) + { + int x = i - kernel_half; + float angle = x * to_angle; + /* instability occurs at center point with rolloff very close to 1.0 */ + if ( x || pow_a_n > (float) 1.056 || pow_a_n < (float) 0.981 ) + { + float rolloff_cos_a = rolloff * (float) cos( angle ); + float num = 1 - rolloff_cos_a - + pow_a_n * (float) cos( maxh * angle ) + + pow_a_n * rolloff * (float) cos( (maxh - 1) * angle ); + float den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff; + float dsf = num / den; + kernels [kernel_size * 3 / 2 - kernel_half + i] = dsf - (float) 0.5; + } + } + + /* apply blackman window and find sum */ + sum = 0; + for ( i = 0; i < kernel_half * 2 + 1; i++ ) + { + float x = PI * 2 / (kernel_half * 2) * i; + float blackman = 0.42f - 0.5f * (float) cos( x ) + 0.08f * (float) cos( x * 2 ); + sum += (kernels [kernel_size * 3 / 2 - kernel_half + i] *= blackman); + } + + /* normalize kernel */ + sum = 1.0f / sum; + for ( i = 0; i < kernel_half * 2 + 1; i++ ) + { + int x = kernel_size * 3 / 2 - kernel_half + i; + kernels [x] *= sum; + assert( kernels [x] == kernels [x] ); /* catch numerical instability */ + } + } + + /* generate chroma (iq) filter using gaussian kernel */ + { + float const cutoff_factor = -0.03125f; + float cutoff = (float) setup->bleed; + int i; + + if ( cutoff < 0 ) + { + /* keep extreme value accessible only near upper end of scale (1.0) */ + cutoff *= cutoff; + cutoff *= cutoff; + cutoff *= cutoff; + cutoff *= -30.0f / 0.65f; + } + cutoff = cutoff_factor - 0.65f * cutoff_factor * cutoff; + + for ( i = -kernel_half; i <= kernel_half; i++ ) + kernels [kernel_size / 2 + i] = (float) exp( i * i * cutoff ); + + /* normalize even and odd phases separately */ + for ( i = 0; i < 2; i++ ) + { + float sum = 0; + int x; + for ( x = i; x < kernel_size; x += 2 ) + sum += kernels [x]; + + sum = 1.0f / sum; + for ( x = i; x < kernel_size; x += 2 ) + { + kernels [x] *= sum; + assert( kernels [x] == kernels [x] ); /* catch numerical instability */ + } + } + } + + /* + printf( "luma:\n" ); + for ( i = kernel_size; i < kernel_size * 2; i++ ) + printf( "%f\n", kernels [i] ); + printf( "chroma:\n" ); + for ( i = 0; i < kernel_size; i++ ) + printf( "%f\n", kernels [i] ); + */ + + /* generate linear rescale kernels */ + #if rescale_out > 1 + { + float weight = 1.0f; + float* out = impl->kernel; + int n = rescale_out; + do + { + float remain = 0; + int i; + weight -= 1.0f / rescale_in; + for ( i = 0; i < kernel_size * 2; i++ ) + { + float cur = kernels [i]; + float m = cur * weight; + *out++ = m + remain; + remain = cur - m; + } + } + while ( --n ); + } + #endif +} + +static float const default_decoder [6] = + { 0.956f, 0.621f, -0.272f, -0.647f, -1.105f, 1.702f }; + +static void init( init_t* impl, sms_ntsc_setup_t const* setup ) +{ + impl->brightness = (float) setup->brightness * (0.5f * rgb_unit) + rgb_offset; + impl->contrast = (float) setup->contrast * (0.5f * rgb_unit) + rgb_unit; + #ifdef default_palette_contrast + if ( !setup->palette ) + impl->contrast *= default_palette_contrast; + #endif + + impl->artifacts = (float) setup->artifacts; + if ( impl->artifacts > 0 ) + impl->artifacts *= artifacts_max - artifacts_mid; + impl->artifacts = impl->artifacts * artifacts_mid + artifacts_mid; + + impl->fringing = (float) setup->fringing; + if ( impl->fringing > 0 ) + impl->fringing *= fringing_max - fringing_mid; + impl->fringing = impl->fringing * fringing_mid + fringing_mid; + + init_filters( impl, setup ); + + /* generate gamma table */ + if ( gamma_size > 1 ) + { + float const to_float = 1.0f / (gamma_size - (gamma_size > 1)); + float const gamma = 1.1333f - (float) setup->gamma * 0.5f; + /* match common PC's 2.2 gamma to TV's 2.65 gamma */ + int i; + for ( i = 0; i < gamma_size; i++ ) + impl->to_float [i] = + (float) pow( i * to_float, gamma ) * impl->contrast + impl->brightness; + } + + /* setup decoder matricies */ + { + float hue = (float) setup->hue * PI + PI / 180 * ext_decoder_hue; + float sat = (float) setup->saturation + 1; + float const* decoder = setup->decoder_matrix; + if ( !decoder ) + { + decoder = default_decoder; + if ( STD_HUE_CONDITION( setup ) ) + hue += PI / 180 * (std_decoder_hue - ext_decoder_hue); + } + + { + float s = (float) sin( hue ) * sat; + float c = (float) cos( hue ) * sat; + float* out = impl->to_rgb; + int n; + + n = burst_count; + do + { + float const* in = decoder; + int n = 3; + do + { + float i = *in++; + float q = *in++; + *out++ = i * c - q * s; + *out++ = i * s + q * c; + } + while ( --n ); + if ( burst_count <= 1 ) + break; + ROTATE_IQ( s, c, 0.866025f, -0.5f ); /* +120 degrees */ + } + while ( --n ); + } + } +} + +/* kernel generation */ + +#define RGB_TO_YIQ( r, g, b, y, i ) (\ + (y = (r) * 0.299f + (g) * 0.587f + (b) * 0.114f),\ + (i = (r) * 0.596f - (g) * 0.275f - (b) * 0.321f),\ + ((r) * 0.212f - (g) * 0.523f + (b) * 0.311f)\ +) + +#define YIQ_TO_RGB( y, i, q, to_rgb, type, r, g ) (\ + r = (type) (y + to_rgb [0] * i + to_rgb [1] * q),\ + g = (type) (y + to_rgb [2] * i + to_rgb [3] * q),\ + (type) (y + to_rgb [4] * i + to_rgb [5] * q)\ +) + +#define PACK_RGB( r, g, b ) ((r) << 21 | (g) << 11 | (b) << 1) + +enum { rgb_kernel_size = burst_size / alignment_count }; +enum { rgb_bias = rgb_unit * 2 * sms_ntsc_rgb_builder }; + +typedef struct pixel_info_t +{ + int offset; + float negate; + float kernel [4]; +} pixel_info_t; + +#if rescale_in > 1 + #define PIXEL_OFFSET_( ntsc, scaled ) \ + (kernel_size / 2 + ntsc + (scaled != 0) + (rescale_out - scaled) % rescale_out + \ + (kernel_size * 2 * scaled)) + + #define PIXEL_OFFSET( ntsc, scaled ) \ + PIXEL_OFFSET_( ((ntsc) - (scaled) / rescale_out * rescale_in),\ + (((scaled) + rescale_out * 10) % rescale_out) ),\ + (1.0f - (((ntsc) + 100) & 2)) +#else + #define PIXEL_OFFSET( ntsc, scaled ) \ + (kernel_size / 2 + (ntsc) - (scaled)),\ + (1.0f - (((ntsc) + 100) & 2)) +#endif + +extern pixel_info_t const sms_ntsc_pixels [alignment_count]; + +/* Generate pixel at all burst phases and column alignments */ +static void gen_kernel( init_t* impl, float y, float i, float q, sms_ntsc_rgb_t* out ) +{ + /* generate for each scanline burst phase */ + float const* to_rgb = impl->to_rgb; + int burst_remain = burst_count; + y -= rgb_offset; + do + { + /* Encode yiq into *two* composite signals (to allow control over artifacting). + Convolve these with kernels which: filter respective components, apply + sharpening, and rescale horizontally. Convert resulting yiq to rgb and pack + into integer. Based on algorithm by NewRisingSun. */ + pixel_info_t const* pixel = sms_ntsc_pixels; + int alignment_remain = alignment_count; + do + { + /* negate is -1 when composite starts at odd multiple of 2 */ + float const yy = y * impl->fringing * pixel->negate; + float const ic0 = (i + yy) * pixel->kernel [0]; + float const qc1 = (q + yy) * pixel->kernel [1]; + float const ic2 = (i - yy) * pixel->kernel [2]; + float const qc3 = (q - yy) * pixel->kernel [3]; + + float const factor = impl->artifacts * pixel->negate; + float const ii = i * factor; + float const yc0 = (y + ii) * pixel->kernel [0]; + float const yc2 = (y - ii) * pixel->kernel [2]; + + float const qq = q * factor; + float const yc1 = (y + qq) * pixel->kernel [1]; + float const yc3 = (y - qq) * pixel->kernel [3]; + + float const* k = &impl->kernel [pixel->offset]; + int n; + ++pixel; + for ( n = rgb_kernel_size; n; --n ) + { + float i = k[0]*ic0 + k[2]*ic2; + float q = k[1]*qc1 + k[3]*qc3; + float y = k[kernel_size+0]*yc0 + k[kernel_size+1]*yc1 + + k[kernel_size+2]*yc2 + k[kernel_size+3]*yc3 + rgb_offset; + if ( rescale_out <= 1 ) + k--; + else if ( k < &impl->kernel [kernel_size * 2 * (rescale_out - 1)] ) + k += kernel_size * 2 - 1; + else + k -= kernel_size * 2 * (rescale_out - 1) + 2; + { + int r, g, b = YIQ_TO_RGB( y, i, q, to_rgb, int, r, g ); + *out++ = PACK_RGB( r, g, b ) - rgb_bias; + } + } + } + while ( alignment_count > 1 && --alignment_remain ); + + if ( burst_count <= 1 ) + break; + + to_rgb += 6; + + ROTATE_IQ( i, q, -0.866025f, -0.5f ); /* -120 degrees */ + } + while ( --burst_remain ); +} + +static void correct_errors( sms_ntsc_rgb_t color, sms_ntsc_rgb_t* out ); + +#if DISABLE_CORRECTION + #define CORRECT_ERROR( a ) { out [i] += rgb_bias; } + #define DISTRIBUTE_ERROR( a, b, c ) { out [i] += rgb_bias; } +#else + #define CORRECT_ERROR( a ) { out [a] += error; } + #define DISTRIBUTE_ERROR( a, b, c ) {\ + sms_ntsc_rgb_t fourth = (error + 2 * sms_ntsc_rgb_builder) >> 2;\ + fourth &= (rgb_bias >> 1) - sms_ntsc_rgb_builder;\ + fourth -= rgb_bias >> 2;\ + out [a] += fourth;\ + out [b] += fourth;\ + out [c] += fourth;\ + out [i] += error - (fourth * 3);\ + } +#endif + +#define RGB_PALETTE_OUT( rgb, out_ )\ +{\ + unsigned char* out = (out_);\ + sms_ntsc_rgb_t clamped = (rgb);\ + SMS_NTSC_CLAMP_( clamped, (8 - rgb_bits) );\ + out [0] = (unsigned char) (clamped >> 21);\ + out [1] = (unsigned char) (clamped >> 11);\ + out [2] = (unsigned char) (clamped >> 1);\ +} + +/* blitter related */ + +#ifndef restrict + #if defined (__GNUC__) + #define restrict __restrict__ + #elif defined (_MSC_VER) && _MSC_VER > 1300 + #define restrict __restrict + #else + /* no support for restricted pointers */ + #define restrict + #endif +#endif + +#include + +#if SMS_NTSC_OUT_DEPTH <= 16 + #if USHRT_MAX == 0xFFFF + typedef unsigned short sms_ntsc_out_t; + #else + #error "Need 16-bit int type" + #endif + +#else + #if UINT_MAX == 0xFFFFFFFF + typedef unsigned int sms_ntsc_out_t; + #elif ULONG_MAX == 0xFFFFFFFF + typedef unsigned long sms_ntsc_out_t; + #else + #error "Need 32-bit int type" + #endif + +#endif diff --git a/genplus-gx/core/shared.h b/genplus-gx/core/shared.h new file mode 100644 index 0000000000..f463aa8ff3 --- /dev/null +++ b/genplus-gx/core/shared.h @@ -0,0 +1,35 @@ +#ifndef _SHARED_H_ +#define _SHARED_H_ + +#include +#include +#include +#include + +#include "types.h" +#include "macros.h" +#include "osd.h" +#include "loadrom.h" +#include "m68k.h" +#include "z80.h" +#include "system.h" +#include "genesis.h" +#include "vdp_ctrl.h" +#include "vdp_render.h" +#include "mem68k.h" +#include "memz80.h" +#include "membnk.h" +#include "io_ctrl.h" +#include "input.h" +#include "sound.h" +#include "sn76489.h" +#include "ym2413.h" +#include "ym2612.h" +#include "sram.h" +#include "ggenie.h" +#include "areplay.h" +#include "svp.h" +#include "state.h" + +#endif /* _SHARED_H_ */ + diff --git a/genplus-gx/core/sound/blip_buf.c b/genplus-gx/core/sound/blip_buf.c new file mode 100644 index 0000000000..307b721337 --- /dev/null +++ b/genplus-gx/core/sound/blip_buf.c @@ -0,0 +1,405 @@ +/* blip_buf $vers. http://www.slack.net/~ant/ */ + +/* Modified for Genesis Plus GX by EkeEke (01/09/12) */ +/* - disabled assertions checks (define #BLIP_ASSERT to re-enable) */ +/* - fixed multiple time-frames support & removed m->avail */ +/* - modified blip_read_samples to always output to stereo streams */ +/* - added blip_mix_samples function (see blip_buf.h) */ + +#include "blip_buf.h" + +#ifdef BLIP_ASSERT +#include +#endif +#include +#include +#include + +/* Library Copyright (C) 2003-2009 Shay Green. This library is free software; +you can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + + +#if defined (BLARGG_TEST) && BLARGG_TEST + #include "blargg_test.h" +#endif + +/* Equivalent to ULONG_MAX >= 0xFFFFFFFF00000000. +Avoids constants that don't fit in 32 bits. */ +#if ULONG_MAX/0xFFFFFFFF > 0xFFFFFFFF + typedef unsigned long fixed_t; + enum { pre_shift = 32 }; + +#elif defined(ULLONG_MAX) + typedef unsigned long long fixed_t; + enum { pre_shift = 32 }; + +#else + typedef unsigned fixed_t; + enum { pre_shift = 0 }; + +#endif + +enum { time_bits = pre_shift + 20 }; + +static fixed_t const time_unit = (fixed_t) 1 << time_bits; + +enum { bass_shift = 9 }; /* affects high-pass filter breakpoint frequency */ +enum { end_frame_extra = 2 }; /* allows deltas slightly after frame length */ + +enum { half_width = 8 }; +enum { buf_extra = half_width*2 + end_frame_extra }; +enum { phase_bits = 5 }; +enum { phase_count = 1 << phase_bits }; +enum { delta_bits = 15 }; +enum { delta_unit = 1 << delta_bits }; +enum { frac_bits = time_bits - pre_shift }; + +/* We could eliminate avail and encode whole samples in offset, but that would +limit the total buffered samples to blip_max_frame. That could only be +increased by decreasing time_bits, which would reduce resample ratio accuracy. +*/ + +struct blip_t +{ + fixed_t factor; + fixed_t offset; + int size; + int integrator; +}; + +typedef int buf_t; + +/* probably not totally portable */ +#define SAMPLES( buf ) ((buf_t*) ((buf) + 1)) + +/* Arithmetic (sign-preserving) right shift */ +#define ARITH_SHIFT( n, shift ) \ + ((n) >> (shift)) + +enum { max_sample = +32767 }; +enum { min_sample = -32768 }; + +#define CLAMP( n ) \ + {\ + if ( n > max_sample ) n = max_sample;\ + else if ( n < min_sample) n = min_sample;\ + } + +#ifdef BLIP_ASSERT +static void check_assumptions( void ) +{ + int n; + + #if INT_MAX < 0x7FFFFFFF || UINT_MAX < 0xFFFFFFFF + #error "int must be at least 32 bits" + #endif + + assert( (-3 >> 1) == -2 ); /* right shift must preserve sign */ + + n = max_sample * 2; + CLAMP( n ); + assert( n == max_sample ); + + n = min_sample * 2; + CLAMP( n ); + assert( n == min_sample ); + + assert( blip_max_ratio <= time_unit ); + assert( blip_max_frame <= (fixed_t) -1 >> time_bits ); +} +#endif + +blip_t* blip_new( int size ) +{ + blip_t* m; +#ifdef BLIP_ASSERT + assert( size >= 0 ); +#endif + + m = (blip_t*) malloc( sizeof *m + (size + buf_extra) * sizeof (buf_t) ); + if ( m ) + { + m->factor = time_unit / blip_max_ratio; + m->size = size; + blip_clear( m ); +#ifdef BLIP_ASSERT + check_assumptions(); +#endif + } + return m; +} + +void blip_delete( blip_t* m ) +{ + if ( m != NULL ) + { + /* Clear fields in case user tries to use after freeing */ + memset( m, 0, sizeof *m ); + free( m ); + } +} + +void blip_set_rates( blip_t* m, double clock_rate, double sample_rate ) +{ + double factor = time_unit * sample_rate / clock_rate; + m->factor = (fixed_t) factor; + +#ifdef BLIP_ASSERT + /* Fails if clock_rate exceeds maximum, relative to sample_rate */ + assert( 0 <= factor - m->factor && factor - m->factor < 1 ); +#endif + +/* Avoid requiring math.h. Equivalent to + m->factor = (int) ceil( factor ) */ + if ( m->factor < factor ) + m->factor++; + + /* At this point, factor is most likely rounded up, but could still + have been rounded down in the floating-point calculation. */ +} + +void blip_clear( blip_t* m ) +{ + /* We could set offset to 0, factor/2, or factor-1. 0 is suitable if + factor is rounded up. factor-1 is suitable if factor is rounded down. + Since we don't know rounding direction, factor/2 accommodates either, + with the slight loss of showing an error in half the time. Since for + a 64-bit factor this is years, the halving isn't a problem. */ + + m->offset = m->factor / 2; + m->integrator = 0; + memset( SAMPLES( m ), 0, (m->size + buf_extra) * sizeof (buf_t) ); +} + +int blip_clocks_needed( const blip_t* m, int samples ) +{ + fixed_t needed; + +#ifdef BLIP_ASSERT + /* Fails if buffer can't hold that many more samples */ + assert( (samples >= 0) && (((m->offset >> time_bits) + samples) <= m->size) ); +#endif + + needed = (fixed_t) samples * time_unit; + if ( needed < m->offset ) + return 0; + + return (needed - m->offset + m->factor - 1) / m->factor; +} + +void blip_end_frame( blip_t* m, unsigned t ) +{ + m->offset += t * m->factor; + +#ifdef BLIP_ASSERT + /* Fails if buffer size was exceeded */ + assert( (m->offset >> time_bits) <= m->size ); +#endif +} + +int blip_samples_avail( const blip_t* m ) +{ + return (m->offset >> time_bits); +} + +static void remove_samples( blip_t* m, int count ) +{ + buf_t* buf = SAMPLES( m ); + int remain = (m->offset >> time_bits) + buf_extra - count; + m->offset -= count * time_unit; + + memmove( &buf [0], &buf [count], remain * sizeof buf [0] ); + memset( &buf [remain], 0, count * sizeof buf [0] ); +} + +int blip_read_samples( blip_t* m, short out [], int count) +{ +#ifdef BLIP_ASSERT + assert( count >= 0 ); + + if ( count > (m->offset >> time_bits) ) + count = m->offset >> time_bits; + + if ( count ) +#endif + { + buf_t const* in = SAMPLES( m ); + buf_t const* end = in + count; + int sum = m->integrator; + do + { + /* Eliminate fraction */ + int s = ARITH_SHIFT( sum, delta_bits ); + + sum += *in++; + + CLAMP( s ); + + *out = s; + out += 2; + + /* High-pass filter */ + sum -= s << (delta_bits - bass_shift); + } + while ( in != end ); + m->integrator = sum; + + remove_samples( m, count ); + } + + return count; +} + +int blip_mix_samples( blip_t* m, short out [], int count) +{ +#ifdef BLIP_ASSERT + assert( count >= 0 ); + + if ( count > (m->offset >> time_bits) ) + count = m->offset >> time_bits; + + if ( count ) +#endif + { + buf_t const* in = SAMPLES( m ); + buf_t const* end = in + count; + int sum = m->integrator; + do + { + /* Eliminate fraction */ + int s = ARITH_SHIFT( sum, delta_bits ); + + sum += *in++; + + /* High-pass filter */ + sum -= s << (delta_bits - bass_shift); + + /* Add current buffer value */ + s += *out; + + CLAMP( s ); + + *out = s; + out += 2; + } + while ( in != end ); + m->integrator = sum; + + remove_samples( m, count ); + } + + return count; +} + +/* Things that didn't help performance on x86: + __attribute__((aligned(128))) + #define short int + restrict +*/ + +/* Sinc_Generator( 0.9, 0.55, 4.5 ) */ +static short const bl_step [phase_count + 1] [half_width] = +{ +{ 43, -115, 350, -488, 1136, -914, 5861,21022}, +{ 44, -118, 348, -473, 1076, -799, 5274,21001}, +{ 45, -121, 344, -454, 1011, -677, 4706,20936}, +{ 46, -122, 336, -431, 942, -549, 4156,20829}, +{ 47, -123, 327, -404, 868, -418, 3629,20679}, +{ 47, -122, 316, -375, 792, -285, 3124,20488}, +{ 47, -120, 303, -344, 714, -151, 2644,20256}, +{ 46, -117, 289, -310, 634, -17, 2188,19985}, +{ 46, -114, 273, -275, 553, 117, 1758,19675}, +{ 44, -108, 255, -237, 471, 247, 1356,19327}, +{ 43, -103, 237, -199, 390, 373, 981,18944}, +{ 42, -98, 218, -160, 310, 495, 633,18527}, +{ 40, -91, 198, -121, 231, 611, 314,18078}, +{ 38, -84, 178, -81, 153, 722, 22,17599}, +{ 36, -76, 157, -43, 80, 824, -241,17092}, +{ 34, -68, 135, -3, 8, 919, -476,16558}, +{ 32, -61, 115, 34, -60, 1006, -683,16001}, +{ 29, -52, 94, 70, -123, 1083, -862,15422}, +{ 27, -44, 73, 106, -184, 1152,-1015,14824}, +{ 25, -36, 53, 139, -239, 1211,-1142,14210}, +{ 22, -27, 34, 170, -290, 1261,-1244,13582}, +{ 20, -20, 16, 199, -335, 1301,-1322,12942}, +{ 18, -12, -3, 226, -375, 1331,-1376,12293}, +{ 15, -4, -19, 250, -410, 1351,-1408,11638}, +{ 13, 3, -35, 272, -439, 1361,-1419,10979}, +{ 11, 9, -49, 292, -464, 1362,-1410,10319}, +{ 9, 16, -63, 309, -483, 1354,-1383, 9660}, +{ 7, 22, -75, 322, -496, 1337,-1339, 9005}, +{ 6, 26, -85, 333, -504, 1312,-1280, 8355}, +{ 4, 31, -94, 341, -507, 1278,-1205, 7713}, +{ 3, 35, -102, 347, -506, 1238,-1119, 7082}, +{ 1, 40, -110, 350, -499, 1190,-1021, 6464}, +{ 0, 43, -115, 350, -488, 1136, -914, 5861} +}; + +/* Shifting by pre_shift allows calculation using unsigned int rather than +possibly-wider fixed_t. On 32-bit platforms, this is likely more efficient. +And by having pre_shift 32, a 32-bit platform can easily do the shift by +simply ignoring the low half. */ + +void blip_add_delta( blip_t* m, unsigned time, int delta ) +{ + unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift); + buf_t* out = SAMPLES( m ) + (fixed >> frac_bits); + + int const phase_shift = frac_bits - phase_bits; + int phase = fixed >> phase_shift & (phase_count - 1); + short const* in = bl_step [phase]; + short const* rev = bl_step [phase_count - phase]; + + int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1); + int delta2 = (delta * interp) >> delta_bits; + delta -= delta2; + +#ifdef BLIP_ASSERT + /* Fails if buffer size was exceeded */ + assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] ); +#endif + + out [0] += in[0]*delta + in[half_width+0]*delta2; + out [1] += in[1]*delta + in[half_width+1]*delta2; + out [2] += in[2]*delta + in[half_width+2]*delta2; + out [3] += in[3]*delta + in[half_width+3]*delta2; + out [4] += in[4]*delta + in[half_width+4]*delta2; + out [5] += in[5]*delta + in[half_width+5]*delta2; + out [6] += in[6]*delta + in[half_width+6]*delta2; + out [7] += in[7]*delta + in[half_width+7]*delta2; + + in = rev; + out [ 8] += in[7]*delta + in[7-half_width]*delta2; + out [ 9] += in[6]*delta + in[6-half_width]*delta2; + out [10] += in[5]*delta + in[5-half_width]*delta2; + out [11] += in[4]*delta + in[4-half_width]*delta2; + out [12] += in[3]*delta + in[3-half_width]*delta2; + out [13] += in[2]*delta + in[2-half_width]*delta2; + out [14] += in[1]*delta + in[1-half_width]*delta2; + out [15] += in[0]*delta + in[0-half_width]*delta2; +} + +void blip_add_delta_fast( blip_t* m, unsigned time, int delta ) +{ + unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift); + buf_t* out = SAMPLES( m ) + (fixed >> frac_bits); + + int interp = fixed >> (frac_bits - delta_bits) & (delta_unit - 1); + int delta2 = delta * interp; + +#ifdef BLIP_ASSERT + /* Fails if buffer size was exceeded */ + assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] ); +#endif + + out [7] += delta * delta_unit - delta2; + out [8] += delta2; +} diff --git a/genplus-gx/core/sound/blip_buf.h b/genplus-gx/core/sound/blip_buf.h new file mode 100644 index 0000000000..21c45d0a15 --- /dev/null +++ b/genplus-gx/core/sound/blip_buf.h @@ -0,0 +1,74 @@ +/** Sample buffer that resamples from input clock rate to output sample rate \file */ + +/* blip_buf $vers */ +#ifndef BLIP_BUF_H +#define BLIP_BUF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** First parameter of most functions is blip_t*, or const blip_t* if nothing +is changed. */ +typedef struct blip_t blip_t; + +/** Creates new buffer that can hold at most sample_count samples. Sets rates +so that there are blip_max_ratio clocks per sample. Returns pointer to new +buffer, or NULL if insufficient memory. */ +blip_t* blip_new( int sample_count ); + +/** Sets approximate input clock rate and output sample rate. For every +clock_rate input clocks, approximately sample_rate samples are generated. */ +void blip_set_rates( blip_t*, double clock_rate, double sample_rate ); + +enum { /** Maximum clock_rate/sample_rate ratio. For a given sample_rate, +clock_rate must not be greater than sample_rate*blip_max_ratio. */ +blip_max_ratio = 1 << 20 }; + +/** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */ +void blip_clear( blip_t* ); + +/** Adds positive/negative delta into buffer at specified clock time. */ +void blip_add_delta( blip_t*, unsigned int clock_time, int delta ); + +/** Same as blip_add_delta(), but uses faster, lower-quality synthesis. */ +void blip_add_delta_fast( blip_t*, unsigned int clock_time, int delta ); + +/** Length of time frame, in clocks, needed to make sample_count additional +samples available. */ +int blip_clocks_needed( const blip_t*, int sample_count ); + +enum { /** Maximum number of samples that can be generated from one time frame. */ +blip_max_frame = 4000 }; + +/** Makes input clocks before clock_duration available for reading as output +samples. Also begins new time frame at clock_duration, so that clock time 0 in +the new time frame specifies the same clock as clock_duration in the old time +frame specified. Deltas can have been added slightly past clock_duration (up to +however many clocks there are in two output samples). */ +void blip_end_frame( blip_t*, unsigned int clock_duration ); + +/** Number of buffered samples available for reading. */ +int blip_samples_avail( const blip_t* ); + +/** Reads and removes at most 'count' samples and writes them to to every other +element of 'out', allowing easy interleaving of two buffers into a stereo sample +stream. Outputs 16-bit signed samples. Returns number of samples actually read. */ +int blip_read_samples( blip_t*, short out [], int count); + +/* Same as above function except sample is added to output buffer previous value */ +/* This allows easy mixing of different blip buffers into a single output stream */ +int blip_mix_samples( blip_t* m, short out [], int count); + +/** Frees buffer. No effect if NULL is passed. */ +void blip_delete( blip_t* ); + + +/* Deprecated */ +typedef blip_t blip_buffer_t; + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/genplus-gx/core/sound/eq.c b/genplus-gx/core/sound/eq.c new file mode 100644 index 0000000000..2f57e2eabf --- /dev/null +++ b/genplus-gx/core/sound/eq.c @@ -0,0 +1,132 @@ +/*---------------------------------------------------------------------------- +// +// 3 Band EQ :) +// +// EQ.C - Main Source file for 3 band EQ +// +// (c) Neil C / Etanza Systems / 2K6 +// +// Shouts / Loves / Moans = etanza at lycos dot co dot uk +// +// This work is hereby placed in the public domain for all purposes, including +// use in commercial applications. +// +// The author assumes NO RESPONSIBILITY for any problems caused by the use of +// this software. +// +//----------------------------------------------------------------------------*/ + +/* NOTES : +// +// - Original filter code by Paul Kellet (musicdsp.pdf) +// +// - Uses 4 first order filters in series, should give 24dB per octave +// +// - Now with P4 Denormal fix :) + + +//----------------------------------------------------------------------------*/ + +/* ---------- +//| Includes | +// ----------*/ +#include +#include +#include +#include "eq.h" +#include "macros.h" + + +/* ----------- +//| Constants | +// -----------*/ + +static double vsa = (1.0 / 4294967295.0); /* Very small amount (Denormal Fix) */ + + +/* --------------- +//| Initialise EQ | +// ---------------*/ + +/* Recommended frequencies are ... +// +// lowfreq = 880 Hz +// highfreq = 5000 Hz +// +// Set mixfreq to whatever rate your system is using (eg 48Khz)*/ + +void init_3band_state(EQSTATE * es, int lowfreq, int highfreq, int mixfreq) +{ + /* Clear state */ + + memset(es, 0, sizeof(EQSTATE)); + + /* Set Low/Mid/High gains to unity */ + + es->lg = 1.0; + es->mg = 1.0; + es->hg = 1.0; + + /* Calculate filter cutoff frequencies */ + + es->lf = 2 * sin(M_PI * ((double) lowfreq / (double) mixfreq)); + es->hf = 2 * sin(M_PI * ((double) highfreq / (double) mixfreq)); +} + + +/* --------------- +//| EQ one sample | +// ---------------*/ + +/* - sample can be any range you like :) +// +// Note that the output will depend on the gain settings for each band +// (especially the bass) so may require clipping before output, but you +// knew that anyway :)*/ + +double do_3band(EQSTATE * es, int sample) +{ + /* Locals */ + + double l, m, h; /* Low / Mid / High - Sample Values */ + + /* Filter #1 (lowpass) */ + + es->f1p0 += (es->lf * ((double) sample - es->f1p0)) + vsa; + es->f1p1 += (es->lf * (es->f1p0 - es->f1p1)); + es->f1p2 += (es->lf * (es->f1p1 - es->f1p2)); + es->f1p3 += (es->lf * (es->f1p2 - es->f1p3)); + + l = es->f1p3; + + /* Filter #2 (highpass) */ + + es->f2p0 += (es->hf * ((double) sample - es->f2p0)) + vsa; + es->f2p1 += (es->hf * (es->f2p0 - es->f2p1)); + es->f2p2 += (es->hf * (es->f2p1 - es->f2p2)); + es->f2p3 += (es->hf * (es->f2p2 - es->f2p3)); + + h = es->sdm3 - es->f2p3; + + /* Calculate midrange (signal - (low + high)) */ + + /* m = es->sdm3 - (h + l); */ + /* fix from http://www.musicdsp.org/showArchiveComment.php?ArchiveID=236 ? */ + m = sample - (h + l); + + /* Scale, Combine and store */ + + l *= es->lg; + m *= es->mg; + h *= es->hg; + + /* Shuffle history buffer */ + + es->sdm3 = es->sdm2; + es->sdm2 = es->sdm1; + es->sdm1 = sample; + + /* Return result */ + + return (int) (l + m + h); +} diff --git a/genplus-gx/core/sound/eq.h b/genplus-gx/core/sound/eq.h new file mode 100644 index 0000000000..d1f37dc56c --- /dev/null +++ b/genplus-gx/core/sound/eq.h @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------- +// +// 3 Band EQ :) +// +// EQ.H - Header file for 3 band EQ +// +// (c) Neil C / Etanza Systems / 2K6 +// +// Shouts / Loves / Moans = etanza at lycos dot co dot uk +// +// This work is hereby placed in the public domain for all purposes, including +// use in commercial applications. +// +// The author assumes NO RESPONSIBILITY for any problems caused by the use of +// this software. +// +//----------------------------------------------------------------------------*/ + +#ifndef __EQ3BAND__ +#define __EQ3BAND__ + +/* ------------ +//| Structures | +// ------------*/ + +typedef struct { + /* Filter #1 (Low band) */ + + double lf; /* Frequency */ + double f1p0; /* Poles ... */ + double f1p1; + double f1p2; + double f1p3; + + /* Filter #2 (High band) */ + + double hf; /* Frequency */ + double f2p0; /* Poles ... */ + double f2p1; + double f2p2; + double f2p3; + + /* Sample history buffer */ + + double sdm1; /* Sample data minus 1 */ + double sdm2; /* 2 */ + double sdm3; /* 3 */ + + /* Gain Controls */ + + double lg; /* low gain */ + double mg; /* mid gain */ + double hg; /* high gain */ + +} EQSTATE; + + +/* --------- +//| Exports | +// ---------*/ + +extern void init_3band_state(EQSTATE * es, int lowfreq, int highfreq, + int mixfreq); +extern double do_3band(EQSTATE * es, int sample); + + +#endif /* #ifndef __EQ3BAND__ */ diff --git a/genplus-gx/core/sound/sn76489.c b/genplus-gx/core/sound/sn76489.c new file mode 100644 index 0000000000..78a051dcb1 --- /dev/null +++ b/genplus-gx/core/sound/sn76489.c @@ -0,0 +1,451 @@ +/* + SN76489 emulation + by Maxim in 2001 and 2002 + converted from my original Delphi implementation + + I'm a C newbie so I'm sure there are loads of stupid things + in here which I'll come back to some day and redo + + Includes: + - Super-high quality tone channel "oversampling" by calculating fractional positions on transitions + - Noise output pattern reverse engineered from actual SMS output + - Volume levels taken from actual SMS output + + 07/08/04 Charles MacDonald + Modified for use with SMS Plus: + - Added support for multiple PSG chips. + - Added reset/config/update routines. + - Added context management routines. + - Removed SN76489_GetValues(). + - Removed some unused variables. + + 25/04/07 Eke-Eke (Genesis Plus GX) + - Removed stereo GG support (unused) + - Made SN76489_Update outputs 16bits mono samples + - Replaced volume table with VGM plugin's one + + 05/01/09 Eke-Eke (Genesis Plus GX) + - Modified Cut-Off frequency (according to Steve Snake: http://www.smspower.org/forums/viewtopic.php?t=1746) + + 24/08/10 Eke-Eke (Genesis Plus GX) + - Removed multichip support (unused) + - Removed alternate volume table, panning & mute support (unused) + - Removed configurable Feedback and Shift Register Width (always use Sega ones) + - Added linear resampling using Blip Buffer (based on Blargg's implementation: http://www.smspower.org/forums/viewtopic.php?t=11376) + + 01/09/12 Eke-Eke (Genesis Plus GX) + - Added generic Blip-Buffer support internally, using common Master Clock as timebase + - Re-added stereo GG support + - Re-added configurable Feedback and Shift Register Width + - Rewrote core with various optimizations +*/ + +#include "shared.h" + +#define PSG_MCYCLES_RATIO (16 * 15) + +/* Initial state of shift register */ +#define NoiseInitialState 0x8000 + +/* Value below which PSG does not output */ +/*#define PSG_CUTOFF 0x6*/ +#define PSG_CUTOFF 0x1 + +/* original Texas Instruments TMS SN76489AN (rev. A) used in SG-1000, SC-3000H & SF-7000 computers */ +#define FB_DISCRETE 0x0006 +#define SRW_DISCRETE 15 + +/* SN76489AN clone integrated in Sega's VDP chips (315-5124, 315-5246, 315-5313, Game Gear) */ +#define FB_SEGAVDP 0x0009 +#define SRW_SEGAVDP 16 + +typedef struct +{ + /* Configuration */ + int PreAmp[4][2]; /* stereo channels pre-amplification ratio (%) */ + int NoiseFeedback; + int SRWidth; + + /* PSG registers: */ + int Registers[8]; /* Tone, vol x4 */ + int LatchedRegister; + int NoiseShiftRegister; + int NoiseFreq; /* Noise channel signal generator frequency */ + + /* Output calculation variables */ + int ToneFreqVals[4]; /* Frequency register values (counters) */ + int ToneFreqPos[4]; /* Frequency channel flip-flops */ + int Channel[4][2]; /* current amplitude of each (stereo) channel */ + int ChanOut[4][2]; /* current output value of each (stereo) channel */ + + /* Internal M-clock counter */ + unsigned long clocks; + +} SN76489_Context; + +static const uint16 PSGVolumeValues[16] = +{ + /* These values are taken from a real SMS2's output */ + /*{892,892,892,760,623,497,404,323,257,198,159,123,96,75,60,0}, */ + /* I can't remember why 892... :P some scaling I did at some point */ + /* these values are true volumes for 2dB drops at each step (multiply previous by 10^-0.1) */ + 1516,1205,957,760,603,479,381,303,240,191,152,120,96,76,60,0 +}; + +static SN76489_Context SN76489; + +static blip_t* blip[2]; + +void SN76489_Init(blip_t* left, blip_t* right, int type) +{ + int i; + + blip[0] = left; + blip[1] = right; + + for (i=0; i<4; i++) + { + SN76489.PreAmp[i][0] = 100; + SN76489.PreAmp[i][1] = 100; + } + + if (type == SN_DISCRETE) + { + SN76489.NoiseFeedback = FB_DISCRETE; + SN76489.SRWidth = SRW_DISCRETE; + } + else + { + SN76489.NoiseFeedback = FB_SEGAVDP; + SN76489.SRWidth = SRW_SEGAVDP; + } +} + +void SN76489_Reset() +{ + int i; + + for(i = 0; i <= 3; i++) + { + /* Initialise PSG state */ + SN76489.Registers[2*i] = 1; /* tone freq=1 */ + SN76489.Registers[2*i+1] = 0xf; /* vol=off */ + + /* Set counters to 0 */ + SN76489.ToneFreqVals[i] = 0; + + /* Set flip-flops to 1 */ + SN76489.ToneFreqPos[i] = 1; + + /* Clear stereo channels amplitude */ + SN76489.Channel[i][0] = 0; + SN76489.Channel[i][1] = 0; + + /* Clear stereo channel outputs in delta buffer */ + SN76489.ChanOut[i][0] = 0; + SN76489.ChanOut[i][1] = 0; + } + + /* Initialise latched register index */ + SN76489.LatchedRegister = 0; + + /* Initialise noise generator */ + SN76489.NoiseShiftRegister=NoiseInitialState; + SN76489.NoiseFreq = 0x10; + + /* Reset internal M-cycle counter */ + SN76489.clocks = 0; +} + +void *SN76489_GetContextPtr(void) +{ + return (uint8 *)&SN76489; +} + +int SN76489_GetContextSize(void) +{ + return sizeof(SN76489_Context); +} + +/* Updates tone amplitude in delta buffer. Call whenever amplitude might have changed. */ +INLINE void UpdateToneAmplitude(int i, int time) +{ + int delta; + + /* left output */ + delta = (SN76489.Channel[i][0] * SN76489.ToneFreqPos[i]) - SN76489.ChanOut[i][0]; + if (delta != 0) + { + SN76489.ChanOut[i][0] += delta; + blip_add_delta_fast(blip[0], time, delta); + } + + /* right output */ + delta = (SN76489.Channel[i][1] * SN76489.ToneFreqPos[i]) - SN76489.ChanOut[i][1]; + if (delta != 0) + { + SN76489.ChanOut[i][1] += delta; + blip_add_delta_fast(blip[1], time, delta); + } +} + +/* Updates noise amplitude in delta buffer. Call whenever amplitude might have changed. */ +INLINE void UpdateNoiseAmplitude(int time) +{ + int delta; + + /* left output */ + delta = (SN76489.Channel[3][0] * ( SN76489.NoiseShiftRegister & 0x1 )) - SN76489.ChanOut[3][0]; + if (delta != 0) + { + SN76489.ChanOut[3][0] += delta; + blip_add_delta_fast(blip[0], time, delta); + } + + /* right output */ + delta = (SN76489.Channel[3][1] * ( SN76489.NoiseShiftRegister & 0x1 )) - SN76489.ChanOut[3][1]; + if (delta != 0) + { + SN76489.ChanOut[3][1] += delta; + blip_add_delta_fast(blip[1], time, delta); + } +} + +/* Runs tone channel for clock_length clocks */ +static void RunTone(int i, int clocks) +{ + int time; + + /* Update in case a register changed etc. */ + UpdateToneAmplitude(i, SN76489.clocks); + + /* Time of next transition */ + time = SN76489.ToneFreqVals[i]; + + /* Process any transitions that occur within clocks we're running */ + while (time < clocks) + { + if (SN76489.Registers[i*2]>PSG_CUTOFF) { + /* Flip the flip-flop */ + SN76489.ToneFreqPos[i] = -SN76489.ToneFreqPos[i]; + } else { + /* stuck value */ + SN76489.ToneFreqPos[i] = 1; + } + UpdateToneAmplitude(i, time); + + /* Advance to time of next transition */ + time += SN76489.Registers[i*2] * PSG_MCYCLES_RATIO; + } + + /* Update channel tone counter */ + SN76489.ToneFreqVals[i] = time; +} + +/* Runs noise channel for clock_length clocks */ +static void RunNoise(int clocks) +{ + int time; + + /* Noise channel: match to tone2 if in slave mode */ + int NoiseFreq = SN76489.NoiseFreq; + if (NoiseFreq == 0x80) + { + NoiseFreq = SN76489.Registers[2*2]; + SN76489.ToneFreqVals[3] = SN76489.ToneFreqVals[2]; + } + + /* Update in case a register changed etc. */ + UpdateNoiseAmplitude(SN76489.clocks); + + /* Time of next transition */ + time = SN76489.ToneFreqVals[3]; + + /* Process any transitions that occur within clocks we're running */ + while (time < clocks) + { + /* Flip the flip-flop */ + SN76489.ToneFreqPos[3] = -SN76489.ToneFreqPos[3]; + if (SN76489.ToneFreqPos[3] == 1) + { + /* On the positive edge of the square wave (only once per cycle) */ + int Feedback = SN76489.NoiseShiftRegister; + if ( SN76489.Registers[6] & 0x4 ) + { + /* White noise */ + /* Calculate parity of fed-back bits for feedback */ + /* Do some optimised calculations for common (known) feedback values */ + /* If two bits fed back, I can do Feedback=(nsr & fb) && (nsr & fb ^ fb) */ + /* since that's (one or more bits set) && (not all bits set) */ + Feedback = ((Feedback & SN76489.NoiseFeedback) && ((Feedback & SN76489.NoiseFeedback) ^ SN76489.NoiseFeedback)); + } + else /* Periodic noise */ + Feedback = Feedback & 1; + + SN76489.NoiseShiftRegister = (SN76489.NoiseShiftRegister >> 1) | (Feedback << (SN76489.SRWidth - 1)); + UpdateNoiseAmplitude(time); + } + + /* Advance to time of next transition */ + time += NoiseFreq * PSG_MCYCLES_RATIO; + } + + /* Update channel tone counter */ + SN76489.ToneFreqVals[3] = time; +} + +static void SN76489_RunUntil(unsigned int clocks) +{ + int i; + + /* Run noise first, since it might use current value of third tone frequency counter */ + RunNoise(clocks); + + /* Run tone channels */ + for (i=0; i<3; ++i) + { + RunTone(i, clocks); + } +} + +void SN76489_Config(unsigned int clocks, int preAmp, int boostNoise, int stereo) +{ + int i; + + /* cycle-accurate Game Gear stereo */ + if (clocks > SN76489.clocks) + { + /* Run chip until current timestamp */ + SN76489_RunUntil(clocks); + + /* Update internal M-cycle counter */ + SN76489.clocks += ((clocks - SN76489.clocks + PSG_MCYCLES_RATIO - 1) / PSG_MCYCLES_RATIO) * PSG_MCYCLES_RATIO; + } + + for (i=0; i<4; i++) + { + /* stereo channel pre-amplification */ + SN76489.PreAmp[i][0] = preAmp * ((stereo >> (i + 4)) & 1); + SN76489.PreAmp[i][1] = preAmp * ((stereo >> (i + 0)) & 1); + + /* noise channel boost */ + if (i == 3) + { + SN76489.PreAmp[3][0] = SN76489.PreAmp[3][0] << boostNoise; + SN76489.PreAmp[3][1] = SN76489.PreAmp[3][1] << boostNoise; + } + + /* update stereo channel amplitude */ + SN76489.Channel[i][0]= (PSGVolumeValues[SN76489.Registers[i*2 + 1]] * SN76489.PreAmp[i][0]) / 100; + SN76489.Channel[i][1]= (PSGVolumeValues[SN76489.Registers[i*2 + 1]] * SN76489.PreAmp[i][1]) / 100; + } +} + +void SN76489_Update(unsigned int clocks) +{ + int i; + + if (clocks > SN76489.clocks) + { + /* Run chip until current timestamp */ + SN76489_RunUntil(clocks); + + /* Update internal M-cycle counter */ + SN76489.clocks += ((clocks - SN76489.clocks + PSG_MCYCLES_RATIO - 1) / PSG_MCYCLES_RATIO) * PSG_MCYCLES_RATIO; + } + + /* Adjust internal M-cycle counter for next frame */ + SN76489.clocks -= clocks; + + /* Adjust channel time counters for new frame */ + for (i=0; i<4; ++i) + { + SN76489.ToneFreqVals[i] -= clocks; + } +} + +void SN76489_Write(unsigned int clocks, unsigned int data) +{ + unsigned int index; + + if (clocks > SN76489.clocks) + { + /* run chip until current timestamp */ + SN76489_RunUntil(clocks); + + /* update internal M-cycle counter */ + SN76489.clocks += ((clocks - SN76489.clocks + PSG_MCYCLES_RATIO - 1) / PSG_MCYCLES_RATIO) * PSG_MCYCLES_RATIO; + } + + if (data & 0x80) + { + /* latch byte %1 cc t dddd */ + SN76489.LatchedRegister = index = (data >> 4) & 0x07; + } + else + { + /* restore latched register index */ + index = SN76489.LatchedRegister; + } + + switch (index) + { + case 0: + case 2: + case 4: /* Tone Channels frequency */ + { + if (data & 0x80) + { + /* Data byte %1 cc t dddd */ + SN76489.Registers[index] = (SN76489.Registers[index] & 0x3f0) | (data & 0xf); + } + else + { + /* Data byte %0 - dddddd */ + SN76489.Registers[index] = (SN76489.Registers[index] & 0x00f) | ((data & 0x3f) << 4); + } + + /* zero frequency behaves the same as a value of 1 */ + if (SN76489.Registers[index] == 0) + { + SN76489.Registers[index] = 1; + } + break; + } + + case 1: + case 3: + case 5: /* Tone Channels attenuation */ + { + data &= 0x0f; + SN76489.Registers[index] = data; + data = PSGVolumeValues[data]; + index >>= 1; + SN76489.Channel[index][0] = (data * SN76489.PreAmp[index][0]) / 100; + SN76489.Channel[index][1] = (data * SN76489.PreAmp[index][1]) / 100; + break; + } + + case 6: /* Noise control */ + { + SN76489.Registers[6] = data & 0x0f; + + /* reset shift register */ + SN76489.NoiseShiftRegister = NoiseInitialState; + + /* set noise signal generator frequency */ + SN76489.NoiseFreq = 0x10 << (data&0x3); + break; + } + + case 7: /* Noise attenuation */ + { + data &= 0x0f; + SN76489.Registers[7] = data; + data = PSGVolumeValues[data]; + SN76489.Channel[3][0] = (data * SN76489.PreAmp[3][0]) / 100; + SN76489.Channel[3][1] = (data * SN76489.PreAmp[3][1]) / 100; + break; + } + } +} diff --git a/genplus-gx/core/sound/sn76489.h b/genplus-gx/core/sound/sn76489.h new file mode 100644 index 0000000000..3c86caeede --- /dev/null +++ b/genplus-gx/core/sound/sn76489.h @@ -0,0 +1,23 @@ +/* + SN76489 emulation + by Maxim in 2001 and 2002 +*/ + +#ifndef _SN76489_H_ +#define _SN76489_H_ + +#include "blip_buf.h" + +#define SN_DISCRETE 0 +#define SN_INTEGRATED 1 + +/* Function prototypes */ +extern void SN76489_Init(blip_t* left, blip_t* right, int type); +extern void SN76489_Reset(void); +extern void SN76489_Config(unsigned int clocks, int preAmp, int boostNoise, int stereo); +extern void SN76489_Write(unsigned int clocks, unsigned int data); +extern void SN76489_Update(unsigned int cycles); +extern void *SN76489_GetContextPtr(void); +extern int SN76489_GetContextSize(void); + +#endif /* _SN76489_H_ */ diff --git a/genplus-gx/core/sound/sound.c b/genplus-gx/core/sound/sound.c new file mode 100644 index 0000000000..7dbbcb07ed --- /dev/null +++ b/genplus-gx/core/sound/sound.c @@ -0,0 +1,275 @@ +/*************************************************************************************** + * Genesis Plus + * Sound Hardware + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "blip_buf.h" + +/* FM output buffer (large enough to hold a whole frame at original chips rate) */ +static int fm_buffer[1080 * 2]; +static int fm_last[2]; +static int *fm_ptr; + +/* Cycle-accurate FM samples */ +static uint32 fm_cycles_ratio; +static uint32 fm_cycles_start; +static uint32 fm_cycles_count; + +/* YM chip function pointers */ +static void (*YM_Reset)(void); +static void (*YM_Update)(int *buffer, int length); +static void (*YM_Write)(unsigned int a, unsigned int v); + +/* Run FM chip until required M-cycles */ +INLINE void fm_update(unsigned int cycles) +{ + if (cycles > fm_cycles_count) + { + /* number of samples to run */ + unsigned int samples = (cycles - fm_cycles_count + fm_cycles_ratio - 1) / fm_cycles_ratio; + + /* run FM chip to sample buffer */ + YM_Update(fm_ptr, samples); + + /* update FM buffer pointer */ + fm_ptr += (samples << 1); + + /* update FM cycle counter */ + fm_cycles_count += samples * fm_cycles_ratio; + } +} + +void sound_init( void ) +{ + /* Initialize FM chip */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* YM2612 */ + YM2612Init(); + YM2612Config(config.dac_bits); + YM_Reset = YM2612ResetChip; + YM_Update = YM2612Update; + YM_Write = YM2612Write; + + /* chip is running a VCLK / 144 = MCLK / 7 / 144 */ + fm_cycles_ratio = 144 * 7; + } + else + { + /* YM2413 */ + YM2413Init(); + YM_Reset = YM2413ResetChip; + YM_Update = YM2413Update; + YM_Write = YM2413Write; + + /* chip is running a ZCLK / 72 = MCLK / 15 / 72 */ + fm_cycles_ratio = 72 * 15; + } + + /* Initialize PSG chip */ + SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff); +} + +void sound_reset(void) +{ + /* reset sound chips */ + YM_Reset(); + SN76489_Reset(); + + /* reset FM buffer ouput */ + fm_last[0] = fm_last[1] = 0; + + /* reset FM buffer pointer */ + fm_ptr = fm_buffer; + + /* reset FM cycle counters */ + fm_cycles_start = fm_cycles_count = 0; +} + +int sound_update(unsigned int cycles) +{ + int delta, preamp, time, l, r, *ptr; + + /* Run PSG & FM chips until end of frame */ + SN76489_Update(cycles); + fm_update(cycles); + + /* FM output pre-amplification */ + preamp = config.fm_preamp; + + /* FM frame initial timestamp */ + time = fm_cycles_start; + + /* Restore last FM outputs from previous frame */ + l = fm_last[0]; + r = fm_last[1]; + + /* FM buffer start pointer */ + ptr = fm_buffer; + + /* flush FM samples */ + if (config.hq_fm) + { + /* high-quality Band-Limited synthesis */ + do + { + /* left channel */ + delta = ((*ptr++ * preamp) / 100) - l; + l += delta; + blip_add_delta(snd.blips[0][0], time, delta); + + /* right channel */ + delta = ((*ptr++ * preamp) / 100) - r; + r += delta; + blip_add_delta(snd.blips[0][1], time, delta); + + /* increment time counter */ + time += fm_cycles_ratio; + } + while (time < cycles); + } + else + { + /* faster Linear Interpolation */ + do + { + /* left channel */ + delta = ((*ptr++ * preamp) / 100) - l; + l += delta; + blip_add_delta_fast(snd.blips[0][0], time, delta); + + /* right channel */ + delta = ((*ptr++ * preamp) / 100) - r; + r += delta; + blip_add_delta_fast(snd.blips[0][1], time, delta); + + /* increment time counter */ + time += fm_cycles_ratio; + } + while (time < cycles); + } + + /* reset FM buffer pointer */ + fm_ptr = fm_buffer; + + /* save last FM output for next frame */ + fm_last[0] = l; + fm_last[1] = r; + + /* adjust FM cycle counters for next frame */ + fm_cycles_count = fm_cycles_start = time - cycles; + + /* end of blip buffers time frame */ + blip_end_frame(snd.blips[0][0], cycles); + blip_end_frame(snd.blips[0][1], cycles); + + /* return number of available samples */ + return blip_samples_avail(snd.blips[0][0]); +} + +int sound_context_save(uint8 *state) +{ + int bufferptr = 0; + + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + bufferptr = YM2612SaveContext(state); + } + else + { + save_param(YM2413GetContextPtr(),YM2413GetContextSize()); + } + + save_param(SN76489_GetContextPtr(),SN76489_GetContextSize()); + + save_param(&fm_cycles_start,sizeof(fm_cycles_start)); + + return bufferptr; +} + +int sound_context_load(uint8 *state) +{ + int bufferptr = 0; + + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + bufferptr = YM2612LoadContext(state); + YM2612Config(config.dac_bits); + } + else + { + load_param(YM2413GetContextPtr(),YM2413GetContextSize()); + } + + load_param(SN76489_GetContextPtr(),SN76489_GetContextSize()); + + load_param(&fm_cycles_start,sizeof(fm_cycles_start)); + fm_cycles_count = fm_cycles_start; + + return bufferptr; +} + +void fm_reset(unsigned int cycles) +{ + /* synchronize FM chip with CPU */ + fm_update(cycles); + + /* reset FM chip */ + YM_Reset(); +} + +void fm_write(unsigned int cycles, unsigned int address, unsigned int data) +{ + /* synchronize FM chip with CPU (on data port write only) */ + if (address & 1) + { + fm_update(cycles); + } + + /* write FM register */ + YM_Write(address, data); +} + +unsigned int fm_read(unsigned int cycles, unsigned int address) +{ + /* synchronize FM chip with CPU */ + fm_update(cycles); + + /* read FM status (YM2612 only) */ + return YM2612Read(); +} diff --git a/genplus-gx/core/sound/sound.h b/genplus-gx/core/sound/sound.h new file mode 100644 index 0000000000..a4284a7abb --- /dev/null +++ b/genplus-gx/core/sound/sound.h @@ -0,0 +1,53 @@ +/*************************************************************************************** + * Genesis Plus + * Sound Hardware + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _SOUND_H_ +#define _SOUND_H_ + +/* Function prototypes */ +extern void sound_init(void); +extern void sound_reset(void); +extern int sound_context_save(uint8 *state); +extern int sound_context_load(uint8 *state); +extern int sound_update(unsigned int cycles); +extern void fm_reset(unsigned int cycles); +extern void fm_write(unsigned int cycles, unsigned int address, unsigned int data); +extern unsigned int fm_read(unsigned int cycles, unsigned int address); + +#endif /* _SOUND_H_ */ diff --git a/genplus-gx/core/sound/ym2413.c b/genplus-gx/core/sound/ym2413.c new file mode 100644 index 0000000000..b71fbdf3dc --- /dev/null +++ b/genplus-gx/core/sound/ym2413.c @@ -0,0 +1,1721 @@ +/* +** +** File: ym2413.c - software implementation of YM2413 +** FM sound generator type OPLL +** +** Copyright (C) 2002 Jarek Burczynski +** +** Version 1.0 +** +** + +to do: + +- make sure of the sinus amplitude bits + +- make sure of the EG resolution bits (looks like the biggest + modulation index generated by the modulator is 123, 124 = no modulation) +- find proper algorithm for attack phase of EG + +- tune up instruments ROM + +- support sample replay in test mode (it is NOT as simple as setting bit 0 + in register 0x0f and using register 0x10 for sample data). + Which games use this feature ? + +*/ + +/** EkeEke (2011): removed multiple chips support, cleaned code & added FM board interface for Genesis Plus GX **/ + +#include "shared.h" + +#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ +#define EG_SH 16 /* 16.16 fixed point (EG timing) */ +#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ + +#define FREQ_MASK ((1<>KSR */ + UINT8 mul; /* multiple: mul_tab[ML] */ + + /* Phase Generator */ + UINT32 phase; /* frequency counter */ + UINT32 freq; /* frequency counter step */ + UINT8 fb_shift; /* feedback shift value */ + INT32 op1_out[2]; /* slot1 output for feedback */ + + /* Envelope Generator */ + UINT8 eg_type; /* percussive/nonpercussive mode */ + UINT8 state; /* phase type */ + UINT32 TL; /* total level: TL << 2 */ + INT32 TLL; /* adjusted now TL */ + INT32 volume; /* envelope counter */ + UINT32 sl; /* sustain level: sl_tab[SL] */ + + UINT8 eg_sh_dp; /* (dump state) */ + UINT8 eg_sel_dp; /* (dump state) */ + UINT8 eg_sh_ar; /* (attack state) */ + UINT8 eg_sel_ar; /* (attack state) */ + UINT8 eg_sh_dr; /* (decay state) */ + UINT8 eg_sel_dr; /* (decay state) */ + UINT8 eg_sh_rr; /* (release state for non-perc.) */ + UINT8 eg_sel_rr; /* (release state for non-perc.) */ + UINT8 eg_sh_rs; /* (release state for perc.mode) */ + UINT8 eg_sel_rs; /* (release state for perc.mode) */ + + UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ + + /* LFO */ + UINT32 AMmask; /* LFO Amplitude Modulation enable mask */ + UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/ + + /* waveform select */ + unsigned int wavetable; +} YM2413_OPLL_SLOT; + +typedef struct +{ + YM2413_OPLL_SLOT SLOT[2]; + + /* phase generator state */ + UINT32 block_fnum; /* block+fnum */ + UINT32 fc; /* Freq. freqement base */ + UINT32 ksl_base; /* KeyScaleLevel Base step */ + UINT8 kcode; /* key code (for key scaling) */ + UINT8 sus; /* sus on/off (release speed in percussive mode) */ +} YM2413_OPLL_CH; + +/* chip state */ +typedef struct { + YM2413_OPLL_CH P_CH[9]; /* OPLL chips have 9 channels */ + UINT8 instvol_r[9]; /* instrument/volume (or volume/volume in percussive mode) */ + + UINT32 eg_cnt; /* global envelope generator counter */ + UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */ + UINT32 eg_timer_add; /* step of eg_timer */ + UINT32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */ + + UINT8 rhythm; /* Rhythm mode */ + + /* LFO */ + UINT32 lfo_am_cnt; + UINT32 lfo_am_inc; + UINT32 lfo_pm_cnt; + UINT32 lfo_pm_inc; + + UINT32 noise_rng; /* 23 bit noise shift register */ + UINT32 noise_p; /* current noise 'phase' */ + UINT32 noise_f; /* current noise period */ + + +/* instrument settings */ +/* + 0-user instrument + 1-15 - fixed instruments + 16 -bass drum settings + 17,18 - other percussion instruments +*/ + UINT8 inst_tab[19][8]; + + UINT32 fn_tab[1024]; /* fnumber->increment counter */ + + UINT8 address; /* address register */ + UINT8 status; /* status flag */ + + double clock; /* master clock (Hz) */ + int rate; /* sampling rate (Hz) */ +} YM2413; + +/* key scale level */ +/* table is 3dB/octave, DV converts this into 6dB/octave */ +/* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */ +#define DV (0.1875/1.0) +static const UINT32 ksl_tab[8*16]= +{ + /* OCT 0 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + /* OCT 1 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV, + 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV, + /* OCT 2 */ + 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV, + 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV, + 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV, + 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV, + /* OCT 3 */ + 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV, + 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV, + 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV, + 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV, + /* OCT 4 */ + 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV, + 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV, + 9.000/DV, 9.750/DV,10.125/DV,10.500/DV, + 10.875/DV,11.250/DV,11.625/DV,12.000/DV, + /* OCT 5 */ + 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV, + 9.000/DV,10.125/DV,10.875/DV,11.625/DV, + 12.000/DV,12.750/DV,13.125/DV,13.500/DV, + 13.875/DV,14.250/DV,14.625/DV,15.000/DV, + /* OCT 6 */ + 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV, + 12.000/DV,13.125/DV,13.875/DV,14.625/DV, + 15.000/DV,15.750/DV,16.125/DV,16.500/DV, + 16.875/DV,17.250/DV,17.625/DV,18.000/DV, + /* OCT 7 */ + 0.000/DV, 9.000/DV,12.000/DV,13.875/DV, + 15.000/DV,16.125/DV,16.875/DV,17.625/DV, + 18.000/DV,18.750/DV,19.125/DV,19.500/DV, + 19.875/DV,20.250/DV,20.625/DV,21.000/DV +}; +#undef DV + +/* sustain level table (3dB per step) */ +/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,45 (dB)*/ +#define SC(db) (UINT32) ( db * (1.0/ENV_STEP) ) +static const UINT32 sl_tab[16]={ + SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7), + SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(15) +}; +#undef SC + + +#define RATE_STEPS (8) +static const unsigned char eg_inc[15*RATE_STEPS]={ + +/*cycle:0 1 2 3 4 5 6 7*/ + +/* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */ +/* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..12 1 */ +/* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..12 2 */ +/* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..12 3 */ + +/* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 13 0 (increment by 1) */ +/* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 13 1 */ +/* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 13 2 */ +/* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 13 3 */ + +/* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 14 0 (increment by 2) */ +/* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 14 1 */ +/*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 14 2 */ +/*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 14 3 */ + +/*12 */ 4,4, 4,4, 4,4, 4,4, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 4) */ +/*13 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 2, 15 3 for attack */ +/*14 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */ +}; + + +#define O(a) (a*RATE_STEPS) + +/*note that there is no O(13) in this table - it's directly in the code */ +static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ +/* 16 infinite time rates */ +O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), +O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), + +/* rates 00-12 */ +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), + +/* rate 13 */ +O( 4),O( 5),O( 6),O( 7), + +/* rate 14 */ +O( 8),O( 9),O(10),O(11), + +/* rate 15 */ +O(12),O(12),O(12),O(12), + +/* 16 dummy rates (same as 15 3) */ +O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), +O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), + +}; +#undef O + +/*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */ +/*shift 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0 */ +/*mask 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0 */ + +#define O(a) (a*1) +static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ +/* 16 infinite time rates */ +O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), +O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), + +/* rates 00-12 */ +O(13),O(13),O(13),O(13), +O(12),O(12),O(12),O(12), +O(11),O(11),O(11),O(11), +O(10),O(10),O(10),O(10), +O( 9),O( 9),O( 9),O( 9), +O( 8),O( 8),O( 8),O( 8), +O( 7),O( 7),O( 7),O( 7), +O( 6),O( 6),O( 6),O( 6), +O( 5),O( 5),O( 5),O( 5), +O( 4),O( 4),O( 4),O( 4), +O( 3),O( 3),O( 3),O( 3), +O( 2),O( 2),O( 2),O( 2), +O( 1),O( 1),O( 1),O( 1), + +/* rate 13 */ +O( 0),O( 0),O( 0),O( 0), + +/* rate 14 */ +O( 0),O( 0),O( 0),O( 0), + +/* rate 15 */ +O( 0),O( 0),O( 0),O( 0), + +/* 16 dummy rates (same as 15 3) */ +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), + +}; +#undef O + + +/* multiple table */ +#define ML 2 +static const UINT8 mul_tab[16]= { +/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */ + 0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML, + 8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML +}; +#undef ML + +/* TL_TAB_LEN is calculated as: +* 11 - sinus amplitude bits (Y axis) +* 2 - sinus sign bit (Y axis) +* TL_RES_LEN - sinus resolution (X axis) +*/ +#define TL_TAB_LEN (11*2*TL_RES_LEN) +static signed int tl_tab[TL_TAB_LEN]; + +#define ENV_QUIET (TL_TAB_LEN>>5) + +/* sin waveform table in 'decibel' scale */ +/* two waveforms on OPLL type chips */ +static unsigned int sin_tab[SIN_LEN * 2]; + + +/* LFO Amplitude Modulation table (verified on real YM3812) + 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples + + Length: 210 elements. + + Each of the elements has to be repeated + exactly 64 times (on 64 consecutive samples). + The whole table takes: 64 * 210 = 13440 samples. + +We use data>>1, until we find what it really is on real chip... + +*/ + +#define LFO_AM_TAB_ELEMENTS 210 + +static const UINT8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = { +0,0,0,0,0,0,0, +1,1,1,1, +2,2,2,2, +3,3,3,3, +4,4,4,4, +5,5,5,5, +6,6,6,6, +7,7,7,7, +8,8,8,8, +9,9,9,9, +10,10,10,10, +11,11,11,11, +12,12,12,12, +13,13,13,13, +14,14,14,14, +15,15,15,15, +16,16,16,16, +17,17,17,17, +18,18,18,18, +19,19,19,19, +20,20,20,20, +21,21,21,21, +22,22,22,22, +23,23,23,23, +24,24,24,24, +25,25,25,25, +26,26,26, +25,25,25,25, +24,24,24,24, +23,23,23,23, +22,22,22,22, +21,21,21,21, +20,20,20,20, +19,19,19,19, +18,18,18,18, +17,17,17,17, +16,16,16,16, +15,15,15,15, +14,14,14,14, +13,13,13,13, +12,12,12,12, +11,11,11,11, +10,10,10,10, +9,9,9,9, +8,8,8,8, +7,7,7,7, +6,6,6,6, +5,5,5,5, +4,4,4,4, +3,3,3,3, +2,2,2,2, +1,1,1,1 +}; + +/* LFO Phase Modulation table (verified on real YM2413) */ +static const INT8 lfo_pm_table[8*8] = { + +/* FNUM2/FNUM = 0 00xxxxxx (0x0000) */ +0, 0, 0, 0, 0, 0, 0, 0, + +/* FNUM2/FNUM = 0 01xxxxxx (0x0040) */ +1, 0, 0, 0,-1, 0, 0, 0, + +/* FNUM2/FNUM = 0 10xxxxxx (0x0080) */ +2, 1, 0,-1,-2,-1, 0, 1, + +/* FNUM2/FNUM = 0 11xxxxxx (0x00C0) */ +3, 1, 0,-1,-3,-1, 0, 1, + +/* FNUM2/FNUM = 1 00xxxxxx (0x0100) */ +4, 2, 0,-2,-4,-2, 0, 2, + +/* FNUM2/FNUM = 1 01xxxxxx (0x0140) */ +5, 2, 0,-2,-5,-2, 0, 2, + +/* FNUM2/FNUM = 1 10xxxxxx (0x0180) */ +6, 3, 0,-3,-6,-3, 0, 3, + +/* FNUM2/FNUM = 1 11xxxxxx (0x01C0) */ +7, 3, 0,-3,-7,-3, 0, 3, +}; + + +/* This is not 100% perfect yet but very close */ +/* + - multi parameters are 100% correct (instruments and drums) + - LFO PM and AM enable are 100% correct + - waveform DC and DM select are 100% correct +*/ + +static unsigned char table[19][8] = { +/* MULT MULT modTL DcDmFb AR/DR AR/DR SL/RR SL/RR */ +/* 0 1 2 3 4 5 6 7 */ + {0x49, 0x4c, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x00 }, /* 0 */ + + {0x61, 0x61, 0x1e, 0x17, 0xf0, 0x78, 0x00, 0x17 }, /* 1 */ + {0x13, 0x41, 0x1e, 0x0d, 0xd7, 0xf7, 0x13, 0x13 }, /* 2 */ + {0x13, 0x01, 0x99, 0x04, 0xf2, 0xf4, 0x11, 0x23 }, /* 3 */ + {0x21, 0x61, 0x1b, 0x07, 0xaf, 0x64, 0x40, 0x27 }, /* 4 */ + +/*{0x22, 0x21, 0x1e, 0x09, 0xf0, 0x76, 0x08, 0x28 }, */ /* 5 */ + {0x22, 0x21, 0x1e, 0x06, 0xf0, 0x75, 0x08, 0x18 }, /* 5 */ + +/*{0x31, 0x22, 0x16, 0x09, 0x90, 0x7f, 0x00, 0x08 }, */ /* 6 */ + {0x31, 0x22, 0x16, 0x05, 0x90, 0x71, 0x00, 0x13 }, /* 6 */ + + {0x21, 0x61, 0x1d, 0x07, 0x82, 0x80, 0x10, 0x17 }, /* 7 */ + {0x23, 0x21, 0x2d, 0x16, 0xc0, 0x70, 0x07, 0x07 }, /* 8 */ + {0x61, 0x61, 0x1b, 0x06, 0x64, 0x65, 0x10, 0x17 }, /* 9 */ + +/* {0x61, 0x61, 0x0c, 0x08, 0x85, 0xa0, 0x79, 0x07 }, */ /* A */ + {0x61, 0x61, 0x0c, 0x18, 0x85, 0xf0, 0x70, 0x07 }, /* A */ + + {0x23, 0x01, 0x07, 0x11, 0xf0, 0xa4, 0x00, 0x22 }, /* B */ + {0x97, 0xc1, 0x24, 0x07, 0xff, 0xf8, 0x22, 0x12 }, /* C */ + +/* {0x61, 0x10, 0x0c, 0x08, 0xf2, 0xc4, 0x40, 0xc8 }, */ /* D */ + {0x61, 0x10, 0x0c, 0x05, 0xf2, 0xf4, 0x40, 0x44 }, /* D */ + + {0x01, 0x01, 0x55, 0x03, 0xf3, 0x92, 0xf3, 0xf3 }, /* E */ + {0x61, 0x41, 0x89, 0x03, 0xf1, 0xf4, 0xf0, 0x13 }, /* F */ + +/* drum instruments definitions */ +/* MULTI MULTI modTL xxx AR/DR AR/DR SL/RR SL/RR */ +/* 0 1 2 3 4 5 6 7 */ + {0x01, 0x01, 0x16, 0x00, 0xfd, 0xf8, 0x2f, 0x6d },/* BD(multi verified, modTL verified, mod env - verified(close), carr. env verifed) */ + {0x01, 0x01, 0x00, 0x00, 0xd8, 0xd8, 0xf9, 0xf8 },/* HH(multi verified), SD(multi not used) */ + {0x05, 0x01, 0x00, 0x00, 0xf8, 0xba, 0x49, 0x55 },/* TOM(multi,env verified), TOP CYM(multi verified, env verified) */ +}; + +static signed int output[2]; + +static UINT32 LFO_AM; +static INT32 LFO_PM; + +/* emulated chip */ +static YM2413 ym2413; + +/* advance LFO to next sample */ +INLINE void advance_lfo(void) +{ + /* LFO */ + ym2413.lfo_am_cnt += ym2413.lfo_am_inc; + if (ym2413.lfo_am_cnt >= (LFO_AM_TAB_ELEMENTS<> LFO_SH ] >> 1; + + ym2413.lfo_pm_cnt += ym2413.lfo_pm_inc; + LFO_PM = (ym2413.lfo_pm_cnt>>LFO_SH) & 7; +} + +/* advance to next sample */ +INLINE void advance(void) +{ + YM2413_OPLL_CH *CH; + YM2413_OPLL_SLOT *op; + unsigned int i; + + /* Envelope Generator */ + ym2413.eg_timer += ym2413.eg_timer_add; + + while (ym2413.eg_timer >= ym2413.eg_timer_overflow) + { + ym2413.eg_timer -= ym2413.eg_timer_overflow; + + ym2413.eg_cnt++; + + for (i=0; i<9*2; i++) + { + CH = &ym2413.P_CH[i>>1]; + + op = &CH->SLOT[i&1]; + + switch(op->state) + { + case EG_DMP: /* dump phase */ + /*dump phase is performed by both operators in each channel*/ + /*when CARRIER envelope gets down to zero level, + ** phases in BOTH opearators are reset (at the same time ?) + */ + if ( !(ym2413.eg_cnt & ((1<eg_sh_dp)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_dp + ((ym2413.eg_cnt>>op->eg_sh_dp)&7)]; + + if ( op->volume >= MAX_ATT_INDEX ) + { + op->volume = MAX_ATT_INDEX; + op->state = EG_ATT; + /* restart Phase Generator */ + op->phase = 0; + } + } + break; + + case EG_ATT: /* attack phase */ + if ( !(ym2413.eg_cnt & ((1<eg_sh_ar)-1) ) ) + { + op->volume += (~op->volume * + (eg_inc[op->eg_sel_ar + ((ym2413.eg_cnt>>op->eg_sh_ar)&7)]) + ) >>2; + + if (op->volume <= MIN_ATT_INDEX) + { + op->volume = MIN_ATT_INDEX; + op->state = EG_DEC; + } + } + break; + + case EG_DEC: /* decay phase */ + if ( !(ym2413.eg_cnt & ((1<eg_sh_dr)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_dr + ((ym2413.eg_cnt>>op->eg_sh_dr)&7)]; + + if ( op->volume >= op->sl ) + op->state = EG_SUS; + } + break; + + case EG_SUS: /* sustain phase */ + /* this is important behaviour: + one can change percusive/non-percussive modes on the fly and + the chip will remain in sustain phase - verified on real YM3812 */ + + if(op->eg_type) /* non-percussive mode (sustained tone) */ + { + /* do nothing */ + } + else /* percussive mode */ + { + /* during sustain phase chip adds Release Rate (in percussive mode) */ + if ( !(ym2413.eg_cnt & ((1<eg_sh_rr)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_rr + ((ym2413.eg_cnt>>op->eg_sh_rr)&7)]; + + if ( op->volume >= MAX_ATT_INDEX ) + op->volume = MAX_ATT_INDEX; + } + /* else do nothing in sustain phase */ + } + break; + + case EG_REL: /* release phase */ + /* exclude modulators in melody channels from performing anything in this mode*/ + /* allowed are only carriers in melody mode and rhythm slots in rhythm mode */ + + /*This table shows which operators and on what conditions are allowed to perform EG_REL: + (a) - always perform EG_REL + (n) - never perform EG_REL + (r) - perform EG_REL in Rhythm mode ONLY + 0: 0 (n), 1 (a) + 1: 2 (n), 3 (a) + 2: 4 (n), 5 (a) + 3: 6 (n), 7 (a) + 4: 8 (n), 9 (a) + 5: 10(n), 11(a) + 6: 12(r), 13(a) + 7: 14(r), 15(a) + 8: 16(r), 17(a) + */ + if ( (i&1) || ((ym2413.rhythm&0x20) && (i>=12)) )/* exclude modulators */ + { + if(op->eg_type) /* non-percussive mode (sustained tone) */ + /*this is correct: use RR when SUS = OFF*/ + /*and use RS when SUS = ON*/ + { + if (CH->sus) + { + if ( !(ym2413.eg_cnt & ((1<eg_sh_rs)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_rs + ((ym2413.eg_cnt>>op->eg_sh_rs)&7)]; + if ( op->volume >= MAX_ATT_INDEX ) + { + op->volume = MAX_ATT_INDEX; + op->state = EG_OFF; + } + } + } + else + { + if ( !(ym2413.eg_cnt & ((1<eg_sh_rr)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_rr + ((ym2413.eg_cnt>>op->eg_sh_rr)&7)]; + if ( op->volume >= MAX_ATT_INDEX ) + { + op->volume = MAX_ATT_INDEX; + op->state = EG_OFF; + } + } + } + } + else /* percussive mode */ + { + if ( !(ym2413.eg_cnt & ((1<eg_sh_rs)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_rs + ((ym2413.eg_cnt>>op->eg_sh_rs)&7)]; + if ( op->volume >= MAX_ATT_INDEX ) + { + op->volume = MAX_ATT_INDEX; + op->state = EG_OFF; + } + } + } + } + break; + + default: + break; + } + } + } + + for (i=0; i<9*2; i++) + { + CH = &ym2413.P_CH[i/2]; + op = &CH->SLOT[i&1]; + + /* Phase Generator */ + if(op->vib) + { + UINT8 block; + + unsigned int fnum_lfo = 8*((CH->block_fnum&0x01c0) >> 6); + unsigned int block_fnum = CH->block_fnum * 2; + signed int lfo_fn_table_index_offset = lfo_pm_table[LFO_PM + fnum_lfo ]; + + if (lfo_fn_table_index_offset) /* LFO phase modulation active */ + { + block_fnum += lfo_fn_table_index_offset; + block = (block_fnum&0x1c00) >> 10; + op->phase += (ym2413.fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul; + } + else /* LFO phase modulation = zero */ + { + op->phase += op->freq; + } + } + else /* LFO phase modulation disabled for this operator */ + { + op->phase += op->freq; + } + } + + /* The Noise Generator of the YM3812 is 23-bit shift register. + * Period is equal to 2^23-2 samples. + * Register works at sampling frequency of the chip, so output + * can change on every sample. + * + * Output of the register and input to the bit 22 is: + * bit0 XOR bit14 XOR bit15 XOR bit22 + * + * Simply use bit 22 as the noise output. + */ + + ym2413.noise_p += ym2413.noise_f; + i = ym2413.noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ + ym2413.noise_p &= FREQ_MASK; + while (i) + { + /* + UINT32 j; + j = ( (chip->noise_rng) ^ (chip->noise_rng>>14) ^ (chip->noise_rng>>15) ^ (chip->noise_rng>>22) ) & 1; + chip->noise_rng = (j<<22) | (chip->noise_rng>>1); + */ + + /* + Instead of doing all the logic operations above, we + use a trick here (and use bit 0 as the noise output). + The difference is only that the noise bit changes one + step ahead. This doesn't matter since we don't know + what is real state of the noise_rng after the reset. + */ + + if (ym2413.noise_rng & 1) ym2413.noise_rng ^= 0x800302; + ym2413.noise_rng >>= 1; + + i--; + } +} + + +INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) +{ + UINT32 p = (env<<5) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<17))) >> FREQ_SH ) & SIN_MASK) ]; + + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; +} + +INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) +{ + UINT32 p = (env<<5) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm)) >> FREQ_SH ) & SIN_MASK) ]; + + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; +} + +#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (LFO_AM & (OP)->AMmask)) + +/* calculate output */ +INLINE void chan_calc( YM2413_OPLL_CH *CH ) +{ + YM2413_OPLL_SLOT *SLOT; + unsigned int env; + signed int out; + signed int phase_modulation; /* phase modulation input (SLOT 2) */ + + /* SLOT 1 */ + SLOT = &CH->SLOT[SLOT1]; + env = volume_calc(SLOT); + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + + SLOT->op1_out[0] = SLOT->op1_out[1]; + phase_modulation = SLOT->op1_out[0]; + + SLOT->op1_out[1] = 0; + + if( env < ENV_QUIET ) + { + if (!SLOT->fb_shift) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->phase, env, (out<fb_shift), SLOT->wavetable ); + } + + /* SLOT 2 */ + + SLOT++; + env = volume_calc(SLOT); + if( env < ENV_QUIET ) + { + output[0] += op_calc(SLOT->phase, env, phase_modulation, SLOT->wavetable); + } +} + +/* + operators used in the rhythm sounds generation process: + + Envelope Generator: + +channel operator register number Bass High Snare Tom Top +/ slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal + 6 / 0 12 50 70 90 f0 + + 6 / 1 15 53 73 93 f3 + + 7 / 0 13 51 71 91 f1 + + 7 / 1 16 54 74 94 f4 + + 8 / 0 14 52 72 92 f2 + + 8 / 1 17 55 75 95 f5 + + + Phase Generator: + +channel operator register number Bass High Snare Tom Top +/ slot number MULTIPLE Drum Hat Drum Tom Cymbal + 6 / 0 12 30 + + 6 / 1 15 33 + + 7 / 0 13 31 + + + + 7 / 1 16 34 ----- n o t u s e d ----- + 8 / 0 14 32 + + 8 / 1 17 35 + + + +channel operator register number Bass High Snare Tom Top +number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal + 6 12,15 B6 A6 + + + 7 13,16 B7 A7 + + + + + 8 14,17 B8 A8 + + + + +*/ + +/* calculate rhythm */ + +INLINE void rhythm_calc( YM2413_OPLL_CH *CH, unsigned int noise ) +{ + YM2413_OPLL_SLOT *SLOT; + signed int out; + unsigned int env; + signed int phase_modulation; /* phase modulation input (SLOT 2) */ + + + /* Bass Drum (verified on real YM3812): + - depends on the channel 6 'connect' register: + when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out) + when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored + - output sample always is multiplied by 2 + */ + + + /* SLOT 1 */ + SLOT = &CH[6].SLOT[SLOT1]; + env = volume_calc(SLOT); + + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + SLOT->op1_out[0] = SLOT->op1_out[1]; + + phase_modulation = SLOT->op1_out[0]; + + SLOT->op1_out[1] = 0; + if( env < ENV_QUIET ) + { + if (!SLOT->fb_shift) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->phase, env, (out<fb_shift), SLOT->wavetable ); + } + + /* SLOT 2 */ + SLOT++; + env = volume_calc(SLOT); + if( env < ENV_QUIET ) + output[1] += op_calc(SLOT->phase, env, phase_modulation, SLOT->wavetable); + + + /* Phase generation is based on: */ + /* HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) */ + /* SD (16) channel 7->slot 1 */ + /* TOM (14) channel 8->slot 1 */ + /* TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) */ + + /* Envelope generation based on: */ + /* HH channel 7->slot1 */ + /* SD channel 7->slot2 */ + /* TOM channel 8->slot1 */ + /* TOP channel 8->slot2 */ + + + /* The following formulas can be well optimized. + I leave them in direct form for now (in case I've missed something). + */ + + /* High Hat (verified on real YM3812) */ + env = volume_calc(&CH[7].SLOT[SLOT1]); + if( env < ENV_QUIET ) + { + + /* high hat phase generation: + phase = d0 or 234 (based on frequency only) + phase = 34 or 2d0 (based on noise) + */ + + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit7 = ((CH[7].SLOT[SLOT1].phase>>FREQ_SH)>>7)&1; + unsigned char bit3 = ((CH[7].SLOT[SLOT1].phase>>FREQ_SH)>>3)&1; + unsigned char bit2 = ((CH[7].SLOT[SLOT1].phase>>FREQ_SH)>>2)&1; + + unsigned char res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0xd0; */ + /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ + UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char bit5e= ((CH[8].SLOT[SLOT2].phase>>FREQ_SH)>>5)&1; + unsigned char bit3e= ((CH[8].SLOT[SLOT2].phase>>FREQ_SH)>>3)&1; + + unsigned char res2 = (bit3e | bit5e); + + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ + if (res2) + phase = (0x200|(0xd0>>2)); + + + /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ + /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ + if (phase&0x200) + { + if (noise) + phase = 0x200|0xd0; + } + else + /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */ + /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */ + { + if (noise) + phase = 0xd0>>2; + } + + output[1] += op_calc(phase<>FREQ_SH)>>8)&1; + + /* when bit8 = 0 phase = 0x100; */ + /* when bit8 = 1 phase = 0x200; */ + UINT32 phase = bit8 ? 0x200 : 0x100; + + /* Noise bit XOR'es phase by 0x100 */ + /* when noisebit = 0 pass the phase from calculation above */ + /* when noisebit = 1 phase ^= 0x100; */ + /* in other words: phase ^= (noisebit<<8); */ + if (noise) + phase ^= 0x100; + + output[1] += op_calc(phase<>FREQ_SH)>>7)&1; + unsigned char bit3 = ((CH[7].SLOT[SLOT1].phase>>FREQ_SH)>>3)&1; + unsigned char bit2 = ((CH[7].SLOT[SLOT1].phase>>FREQ_SH)>>2)&1; + + unsigned char res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0x100; */ + /* when res1 = 1 phase = 0x200 | 0x100; */ + UINT32 phase = res1 ? 0x300 : 0x100; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char bit5e= ((CH[8].SLOT[SLOT2].phase>>FREQ_SH)>>5)&1; + unsigned char bit3e= ((CH[8].SLOT[SLOT2].phase>>FREQ_SH)>>3)&1; + + unsigned char res2 = (bit3e | bit5e); + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | 0x100; */ + if (res2) + phase = 0x300; + + output[1] += op_calc(phase<>= 4; /* 12 bits here */ + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + /* 11 bits here (rounded) */ + tl_tab[ x*2 + 0 ] = n; + tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ]; + + for (i=1; i<11; i++) + { + tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; + tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; + } + } + + for (i=0; i0.0) + o = 8*log(1.0/m)/log(2); /* convert to 'decibels' */ + else + o = 8*log(-1.0/m)/log(2); /* convert to 'decibels' */ + + o = o / (ENV_STEP/4); + + n = (int)(2.0*o); + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + + /* waveform 0: standard sinus */ + sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); + + /* waveform 1: __ __ */ + /* / \____/ \____*/ + /* output only first half of the sinus waveform (positive one) */ + if (i & (1<<(SIN_BITS-1)) ) + sin_tab[1*SIN_LEN+i] = TL_TAB_LEN; + else + sin_tab[1*SIN_LEN+i] = sin_tab[i]; + } + + return 1; +} + + +static void OPLL_initalize(void) +{ + int i; + + /* YM2413 always running at original frequency */ + double freqbase = 1.0; + + /* make fnumber -> increment counter table */ + for( i = 0 ; i < 1024; i++ ) + { + /* OPLL (YM2413) phase increment counter = 18bit */ + ym2413.fn_tab[i] = (UINT32)( (double)i * 64 * freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ + } + + /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ + /* One entry from LFO_AM_TABLE lasts for 64 samples */ + ym2413.lfo_am_inc = (1.0 / 64.0 ) * (1<key ) + { + /* do NOT restart Phase Generator (verified on real YM2413)*/ + /* phase -> Dump */ + SLOT->state = EG_DMP; + } + SLOT->key |= key_set; +} + +INLINE void KEY_OFF(YM2413_OPLL_SLOT *SLOT, UINT32 key_clr) +{ + if( SLOT->key ) + { + SLOT->key &= key_clr; + + if( !SLOT->key ) + { + /* phase -> Release */ + if (SLOT->state>EG_REL) + SLOT->state = EG_REL; + } + } +} + +/* update phase increment counter of operator (also update the EG rates if necessary) */ +INLINE void CALC_FCSLOT(YM2413_OPLL_CH *CH,YM2413_OPLL_SLOT *SLOT) +{ + int ksr; + UINT32 SLOT_rs; + UINT32 SLOT_dp; + + /* (frequency) phase increment counter */ + SLOT->freq = CH->fc * SLOT->mul; + ksr = CH->kcode >> SLOT->KSR; + + if( SLOT->ksr != ksr ) + { + SLOT->ksr = ksr; + + /* calculate envelope generator rates */ + if ((SLOT->ar + SLOT->ksr) < 16+62) + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } + else + { + SLOT->eg_sh_ar = 0; + SLOT->eg_sel_ar = 13*RATE_STEPS; + } + SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; + SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; + + } + + if (CH->sus) + SLOT_rs = 16 + (5<<2); + else + SLOT_rs = 16 + (7<<2); + + SLOT->eg_sh_rs = eg_rate_shift [SLOT_rs + SLOT->ksr ]; + SLOT->eg_sel_rs = eg_rate_select[SLOT_rs + SLOT->ksr ]; + + SLOT_dp = 16 + (13<<2); + SLOT->eg_sh_dp = eg_rate_shift [SLOT_dp + SLOT->ksr ]; + SLOT->eg_sel_dp = eg_rate_select[SLOT_dp + SLOT->ksr ]; +} + +/* set multi,am,vib,EG-TYP,KSR,mul */ +INLINE void set_mul(int slot,int v) +{ + YM2413_OPLL_CH *CH = &ym2413.P_CH[slot/2]; + YM2413_OPLL_SLOT *SLOT = &CH->SLOT[slot&1]; + + SLOT->mul = mul_tab[v&0x0f]; + SLOT->KSR = (v&0x10) ? 0 : 2; + SLOT->eg_type = (v&0x20); + SLOT->vib = (v&0x40); + SLOT->AMmask = (v&0x80) ? ~0 : 0; + CALC_FCSLOT(CH,SLOT); +} + +/* set ksl, tl */ +INLINE void set_ksl_tl(int chan,int v) +{ + YM2413_OPLL_CH *CH = &ym2413.P_CH[chan]; + /* modulator */ + YM2413_OPLL_SLOT *SLOT = &CH->SLOT[SLOT1]; + + int ksl = v>>6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */ + + SLOT->ksl = ksl ? 3-ksl : 31; + SLOT->TL = (v&0x3f)<<(ENV_BITS-2-7); /* 7 bits TL (bit 6 = always 0) */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); +} + +/* set ksl , waveforms, feedback */ +INLINE void set_ksl_wave_fb(int chan,int v) +{ + YM2413_OPLL_CH *CH = &ym2413.P_CH[chan]; + /* modulator */ + YM2413_OPLL_SLOT *SLOT = &CH->SLOT[SLOT1]; + SLOT->wavetable = ((v&0x08)>>3)*SIN_LEN; + SLOT->fb_shift = (v&7) ? (v&7) + 8 : 0; + + /*carrier*/ + SLOT = &CH->SLOT[SLOT2]; + SLOT->wavetable = ((v&0x10)>>4)*SIN_LEN; + v >>= 6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */ + SLOT->ksl = v ? 3-v : 31; + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); +} + +/* set attack rate & decay rate */ +INLINE void set_ar_dr(int slot,int v) +{ + YM2413_OPLL_CH *CH = &ym2413.P_CH[slot/2]; + YM2413_OPLL_SLOT *SLOT = &CH->SLOT[slot&1]; + + SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0; + + if ((SLOT->ar + SLOT->ksr) < 16+62) + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } + else + { + SLOT->eg_sh_ar = 0; + SLOT->eg_sel_ar = 13*RATE_STEPS; + } + + SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; + SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; +} + +/* set sustain level & release rate */ +INLINE void set_sl_rr(int slot,int v) +{ + YM2413_OPLL_CH *CH = &ym2413.P_CH[slot/2]; + YM2413_OPLL_SLOT *SLOT = &CH->SLOT[slot&1]; + + SLOT->sl = sl_tab[ v>>4 ]; + + SLOT->rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; +} + +static void load_instrument(UINT32 chan, UINT32 slot, UINT8* inst ) +{ + set_mul(slot, inst[0]); + set_mul(slot+1, inst[1]); + set_ksl_tl(chan, inst[2]); + set_ksl_wave_fb(chan, inst[3]); + set_ar_dr(slot, inst[4]); + set_ar_dr(slot+1, inst[5]); + set_sl_rr(slot, inst[6]); + set_sl_rr(slot+1, inst[7]); +} + +static void update_instrument_zero(UINT8 r) +{ + UINT8* inst = &ym2413.inst_tab[0][0]; /* point to user instrument */ + UINT32 chan; + + UINT32 chan_max = 9; + if (ym2413.rhythm & 0x20) + chan_max=6; + + switch(r&7) + { + case 0: + for (chan=0; chanSLOT[SLOT1]; /* modulator envelope is HH */ + SLOT->TL = ((ym2413.instvol_r[7]>>4)<<2)<<(ENV_BITS-2-7); /* 7 bits TL (bit 6 = always 0) */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + + /* Load instrument settings for channel nine. (Tom-tom and top cymbal) */ + load_instrument(8, 16, &ym2413.inst_tab[18][0]); + + CH = &ym2413.P_CH[8]; + SLOT = &CH->SLOT[SLOT1]; /* modulator envelope is TOM */ + SLOT->TL = ((ym2413.instvol_r[8]>>4)<<2)<<(ENV_BITS-2-7); /* 7 bits TL (bit 6 = always 0) */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + } + + /* BD key on/off */ + if(v&0x10) + { + KEY_ON (&ym2413.P_CH[6].SLOT[SLOT1], 2); + KEY_ON (&ym2413.P_CH[6].SLOT[SLOT2], 2); + } + else + { + KEY_OFF(&ym2413.P_CH[6].SLOT[SLOT1],~2); + KEY_OFF(&ym2413.P_CH[6].SLOT[SLOT2],~2); + } + + /* HH key on/off */ + if(v&0x01) KEY_ON (&ym2413.P_CH[7].SLOT[SLOT1], 2); + else KEY_OFF(&ym2413.P_CH[7].SLOT[SLOT1],~2); + + /* SD key on/off */ + if(v&0x08) KEY_ON (&ym2413.P_CH[7].SLOT[SLOT2], 2); + else KEY_OFF(&ym2413.P_CH[7].SLOT[SLOT2],~2); + + /* TOM key on/off */ + if(v&0x04) KEY_ON (&ym2413.P_CH[8].SLOT[SLOT1], 2); + else KEY_OFF(&ym2413.P_CH[8].SLOT[SLOT1],~2); + + /* TOP-CY key on/off */ + if(v&0x02) KEY_ON (&ym2413.P_CH[8].SLOT[SLOT2], 2); + else KEY_OFF(&ym2413.P_CH[8].SLOT[SLOT2],~2); + } + else + { + /* rhythm ON to OFF */ + if (ym2413.rhythm&0x20) + { + /* Load instrument settings for channel seven(chan=6 since we're zero based).*/ + load_instrument(6, 12, &ym2413.inst_tab[ym2413.instvol_r[6]>>4][0]); + + /* Load instrument settings for channel eight.*/ + load_instrument(7, 14, &ym2413.inst_tab[ym2413.instvol_r[7]>>4][0]); + + /* Load instrument settings for channel nine.*/ + load_instrument(8, 16, &ym2413.inst_tab[ym2413.instvol_r[8]>>4][0]); + } + + /* BD key off */ + KEY_OFF(&ym2413.P_CH[6].SLOT[SLOT1],~2); + KEY_OFF(&ym2413.P_CH[6].SLOT[SLOT2],~2); + + /* HH key off */ + KEY_OFF(&ym2413.P_CH[7].SLOT[SLOT1],~2); + + /* SD key off */ + KEY_OFF(&ym2413.P_CH[7].SLOT[SLOT2],~2); + + /* TOM key off */ + KEY_OFF(&ym2413.P_CH[8].SLOT[SLOT1],~2); + + /* TOP-CY off */ + KEY_OFF(&ym2413.P_CH[8].SLOT[SLOT2],~2); + } + + ym2413.rhythm = v&0x3f; + break; + } + } + + break; + } + + case 0x10: + case 0x20: + { + int block_fnum; + + int chan = r&0x0f; + + if (chan >= 9) + chan -= 9; /* verified on real YM2413 */ + + CH = &ym2413.P_CH[chan]; + + if(r&0x10) + { + /* 10-18: FNUM 0-7 */ + block_fnum = (CH->block_fnum&0x0f00) | v; + } + else + { + /* 20-28: suson, keyon, block, FNUM 8 */ + block_fnum = ((v&0x0f)<<8) | (CH->block_fnum&0xff); + + if(v&0x10) + { + KEY_ON (&CH->SLOT[SLOT1], 1); + KEY_ON (&CH->SLOT[SLOT2], 1); + } + else + { + KEY_OFF(&CH->SLOT[SLOT1],~1); + KEY_OFF(&CH->SLOT[SLOT2],~1); + } + + CH->sus = v & 0x20; + } + + /* update */ + if(CH->block_fnum != block_fnum) + { + UINT8 block; + CH->block_fnum = block_fnum; + + /* BLK 2,1,0 bits -> bits 3,2,1 of kcode, FNUM MSB -> kcode LSB */ + CH->kcode = (block_fnum&0x0f00)>>8; + + CH->ksl_base = ksl_tab[block_fnum>>5]; + + block_fnum = block_fnum * 2; + block = (block_fnum&0x1c00) >> 10; + CH->fc = ym2413.fn_tab[block_fnum&0x03ff] >> (7-block); + + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + } + + break; + } + + case 0x30: /* inst 4 MSBs, VOL 4 LSBs */ + { + int chan = r&0x0f; + + if (chan >= 9) + chan -= 9; /* verified on real YM2413 */ + + CH = &ym2413.P_CH[chan]; + SLOT = &CH->SLOT[SLOT2]; /* carrier */ + SLOT->TL = ((v&0x0f)<<2)<<(ENV_BITS-2-7); /* 7 bits TL (bit 6 = always 0) */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + + /*check wether we are in rhythm mode and handle instrument/volume register accordingly*/ + if ((chan>=6) && (ym2413.rhythm&0x20)) + { + /* we're in rhythm mode*/ + + if (chan>=7) /* only for channel 7 and 8 (channel 6 is handled in usual way)*/ + { + SLOT = &CH->SLOT[SLOT1]; /* modulator envelope is HH(chan=7) or TOM(chan=8) */ + SLOT->TL = ((v>>4)<<2)<<(ENV_BITS-2-7); /* 7 bits TL (bit 6 = always 0) */ + SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + } + } + else + { + if ((ym2413.instvol_r[chan]&0xf0) != (v&0xf0)) + { + ym2413.instvol_r[chan] = v; /* store for later use */ + load_instrument(chan, chan * 2, &ym2413.inst_tab[v>>4][0]); + } + } + + break; + } + + default: + break; + } +} + + +void YM2413Init(void) +{ + init_tables(); + + /* clear */ + memset(&ym2413,0,sizeof(YM2413)); + + /* init global tables */ + OPLL_initalize(); +} + +void YM2413ResetChip(void) +{ + int c,s; + int i; + + ym2413.eg_timer = 0; + ym2413.eg_cnt = 0; + + ym2413.noise_rng = 1; /* noise shift register */ + + + /* setup instruments table */ + for (i=0; i<19; i++) + { + for (c=0; c<8; c++) + { + ym2413.inst_tab[i][c] = table[i][c]; + } + } + + + /* reset with register write */ + OPLLWriteReg(0x0f,0); /*test reg*/ + for(i = 0x3f ; i >= 0x10 ; i-- ) OPLLWriteReg(i,0x00); + + /* reset operator parameters */ + for( c = 0 ; c < 9 ; c++ ) + { + YM2413_OPLL_CH *CH = &ym2413.P_CH[c]; + for(s = 0 ; s < 2 ; s++ ) + { + /* wave table */ + CH->SLOT[s].wavetable = 0; + CH->SLOT[s].state = EG_OFF; + CH->SLOT[s].volume = MAX_ATT_INDEX; + } + } +} + +/* YM2413 I/O interface */ + +void YM2413Write(unsigned int a, unsigned int v) +{ + if( !(a&2) ) + { + if( !(a&1) ) + { + /* address port */ + ym2413.address = v & 0xff; + } + else + { + /* data port */ + OPLLWriteReg(ym2413.address,v); + } + } + else + { + /* latched bit (Master System specific) */ + ym2413.status = v & 0x01; + } +} + +unsigned int YM2413Read(unsigned int a) +{ + /* D0=latched bit, D1-D2 need to be zero (Master System specific) */ + return 0xF8 | ym2413.status; +} + +void YM2413Update(int *buffer, int length) +{ + int i, out; + + for( i=0; i < length ; i++ ) + { + output[0] = 0; + output[1] = 0; + + advance_lfo(); + + /* FM part */ + chan_calc(&ym2413.P_CH[0]); + chan_calc(&ym2413.P_CH[1]); + chan_calc(&ym2413.P_CH[2]); + chan_calc(&ym2413.P_CH[3]); + chan_calc(&ym2413.P_CH[4]); + chan_calc(&ym2413.P_CH[5]); + + if(!(ym2413.rhythm&0x20)) + { + chan_calc(&ym2413.P_CH[6]); + chan_calc(&ym2413.P_CH[7]); + chan_calc(&ym2413.P_CH[8]); + } + else /* Rhythm part */ + { + rhythm_calc(&ym2413.P_CH[0], (ym2413.noise_rng>>0)&1 ); + } + + /* Melody (MO) & Rythm (RO) outputs mixing & amplification (latched bit controls FM output) */ + out = (output[0] + (output[1] * 2)) * 2 * ym2413.status; + + /* Store to stereo sound buffer */ + *buffer++ = out; + *buffer++ = out; + + advance(); + } +} + +unsigned char *YM2413GetContextPtr(void) +{ + return (unsigned char *)&ym2413; +} + +unsigned int YM2413GetContextSize(void) +{ + return sizeof(YM2413); +} diff --git a/genplus-gx/core/sound/ym2413.h b/genplus-gx/core/sound/ym2413.h new file mode 100644 index 0000000000..73c8c84b48 --- /dev/null +++ b/genplus-gx/core/sound/ym2413.h @@ -0,0 +1,23 @@ +/* +** +** File: ym2413.c - software implementation of YM2413 +** FM sound generator type OPLL +** +** Copyright (C) 2002 Jarek Burczynski +** +** Version 1.0 +** +*/ + +#ifndef _H_YM2413_ +#define _H_YM2413_ + +extern void YM2413Init(void); +extern void YM2413ResetChip(void); +extern void YM2413Update(int *buffer, int length); +extern void YM2413Write(unsigned int a, unsigned int v); +extern unsigned int YM2413Read(unsigned int a); +extern unsigned char *YM2413GetContextPtr(void); +extern unsigned int YM2413GetContextSize(void); + +#endif /*_H_YM2413_*/ diff --git a/genplus-gx/core/sound/ym2612.c b/genplus-gx/core/sound/ym2612.c new file mode 100644 index 0000000000..210f386f09 --- /dev/null +++ b/genplus-gx/core/sound/ym2612.c @@ -0,0 +1,2178 @@ +/* +** +** software implementation of Yamaha FM sound generator (YM2612/YM3438) +** +** Original code (MAME fm.c) +** +** Copyright (C) 2001, 2002, 2003 Jarek Burczynski (bujar at mame dot net) +** Copyright (C) 1998 Tatsuyuki Satoh , MultiArcadeMachineEmulator development +** +** Version 1.4 (final beta) +** +** Additional code & fixes by Eke-Eke for Genesis Plus GX +** +** Huge thanks to Nemesis, most of those fixes came from his tests on Sega Genesis hardware +** More informations at http://gendev.spritesmind.net/forum/viewtopic.php?t=386 +** +** TODO: +** - better documentation +** - BUSY flag emulation +*/ + +/* +** CHANGELOG: +** +** 01-09-2012 Eke-Eke (Genesis Plus GX): +** - removed input clock / output samplerate frequency ratio, chip now always run at (original) internal sample frequency +** - removed now uneeded extra bits of precision +** +** 2006~2012 Eke-Eke (Genesis Plus GX): +** - removed unused multichip support +** - added YM2612 Context external access functions +** - fixed LFO implementation: +** .added support for CH3 special mode: fixes various sound effects (birds in Warlock, bug sound in Aladdin...) +** .inverted LFO AM waveform: fixes Spider-Man & Venom : Separation Anxiety (intro), California Games (surfing event) +** .improved LFO timing accuracy: now updated AFTER sample output, like EG/PG updates, and without any precision loss anymore. +** - improved internal timers emulation +** - adjusted lowest EG rates increment values +** - fixed Attack Rate not being updated in some specific cases (Batman & Robin intro) +** - fixed EG behavior when Attack Rate is maximal +** - fixed EG behavior when SL=0 (Mega Turrican tracks 03,09...) or/and Key ON occurs at minimal attenuation +** - implemented EG output immediate changes on register writes +** - fixed YM2612 initial values (after the reset): fixes missing intro in B.O.B +** - implemented Detune overflow (Ariel, Comix Zone, Shaq Fu, Spiderman & many other games using GEMS sound engine) +** - implemented accurate CSM mode emulation +** - implemented accurate SSG-EG emulation (Asterix, Beavis&Butthead, Bubba'n Stix & many other games) +** - implemented accurate address/data ports behavior +** - added preliminar support for DAC precision +** +** 03-08-2003 Jarek Burczynski: +** - fixed YM2608 initial values (after the reset) +** - fixed flag and irqmask handling (YM2608) +** - fixed BUFRDY flag handling (YM2608) +** +** 14-06-2003 Jarek Burczynski: +** - implemented all of the YM2608 status register flags +** - implemented support for external memory read/write via YM2608 +** - implemented support for deltat memory limit register in YM2608 emulation +** +** 22-05-2003 Jarek Burczynski: +** - fixed LFO PM calculations (copy&paste bugfix) +** +** 08-05-2003 Jarek Burczynski: +** - fixed SSG support +** +** 22-04-2003 Jarek Burczynski: +** - implemented 100% correct LFO generator (verified on real YM2610 and YM2608) +** +** 15-04-2003 Jarek Burczynski: +** - added support for YM2608's register 0x110 - status mask +** +** 01-12-2002 Jarek Burczynski: +** - fixed register addressing in YM2608, YM2610, YM2610B chips. (verified on real YM2608) +** The addressing patch used for early Neo-Geo games can be removed now. +** +** 26-11-2002 Jarek Burczynski, Nicola Salmoria: +** - recreated YM2608 ADPCM ROM using data from real YM2608's output which leads to: +** - added emulation of YM2608 drums. +** - output of YM2608 is two times lower now - same as YM2610 (verified on real YM2608) +** +** 16-08-2002 Jarek Burczynski: +** - binary exact Envelope Generator (verified on real YM2203); +** identical to YM2151 +** - corrected 'off by one' error in feedback calculations (when feedback is off) +** - corrected connection (algorithm) calculation (verified on real YM2203 and YM2610) +** +** 18-12-2001 Jarek Burczynski: +** - added SSG-EG support (verified on real YM2203) +** +** 12-08-2001 Jarek Burczynski: +** - corrected sin_tab and tl_tab data (verified on real chip) +** - corrected feedback calculations (verified on real chip) +** - corrected phase generator calculations (verified on real chip) +** - corrected envelope generator calculations (verified on real chip) +** - corrected FM volume level (YM2610 and YM2610B). +** - changed YMxxxUpdateOne() functions (YM2203, YM2608, YM2610, YM2610B, YM2612) : +** this was needed to calculate YM2610 FM channels output correctly. +** (Each FM channel is calculated as in other chips, but the output of the channel +** gets shifted right by one *before* sending to accumulator. That was impossible to do +** with previous implementation). +** +** 23-07-2001 Jarek Burczynski, Nicola Salmoria: +** - corrected YM2610 ADPCM type A algorithm and tables (verified on real chip) +** +** 11-06-2001 Jarek Burczynski: +** - corrected end of sample bug in ADPCMA_calc_cha(). +** Real YM2610 checks for equality between current and end addresses (only 20 LSB bits). +** +** 08-12-98 hiro-shi: +** rename ADPCMA -> ADPCMB, ADPCMB -> ADPCMA +** move ROM limit check.(CALC_CH? -> 2610Write1/2) +** test program (ADPCMB_TEST) +** move ADPCM A/B end check. +** ADPCMB repeat flag(no check) +** change ADPCM volume rate (8->16) (32->48). +** +** 09-12-98 hiro-shi: +** change ADPCM volume. (8->16, 48->64) +** replace ym2610 ch0/3 (YM-2610B) +** change ADPCM_SHIFT (10->8) missing bank change 0x4000-0xffff. +** add ADPCM_SHIFT_MASK +** change ADPCMA_DECODE_MIN/MAX. +*/ + +/************************************************************************/ +/* comment of hiro-shi(Hiromitsu Shioya) */ +/* YM2610(B) = OPN-B */ +/* YM2610 : PSG:3ch FM:4ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */ +/* YM2610B : PSG:3ch FM:6ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */ +/************************************************************************/ + +#include "shared.h" + +/* envelope generator */ +#define ENV_BITS 10 +#define ENV_LEN (1<>3) + +/* sin waveform table in 'decibel' scale */ +static unsigned int sin_tab[SIN_LEN]; + +/* sustain level table (3dB per step) */ +/* bit0, bit1, bit2, bit3, bit4, bit5, bit6 */ +/* 1, 2, 4, 8, 16, 32, 64 (value)*/ +/* 0.75, 1.5, 3, 6, 12, 24, 48 (dB)*/ + +/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ +/* attenuation value (10 bits) = (SL << 2) << 3 */ +#define SC(db) (UINT32) ( db * (4.0/ENV_STEP) ) +static const UINT32 sl_table[16]={ + SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7), + SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) +}; +#undef SC + + +#define RATE_STEPS (8) +static const UINT8 eg_inc[19*RATE_STEPS]={ + +/*cycle:0 1 2 3 4 5 6 7*/ + +/* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..11 0 (increment by 0 or 1) */ +/* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..11 1 */ +/* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..11 2 */ +/* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..11 3 */ + +/* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 12 0 (increment by 1) */ +/* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 12 1 */ +/* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 12 2 */ +/* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 12 3 */ + +/* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 13 0 (increment by 2) */ +/* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 13 1 */ +/*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 13 2 */ +/*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 13 3 */ + +/*12 */ 4,4, 4,4, 4,4, 4,4, /* rate 14 0 (increment by 4) */ +/*13 */ 4,4, 4,8, 4,4, 4,8, /* rate 14 1 */ +/*14 */ 4,8, 4,8, 4,8, 4,8, /* rate 14 2 */ +/*15 */ 4,8, 8,8, 4,8, 8,8, /* rate 14 3 */ + +/*16 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 8) */ +/*17 */ 16,16,16,16,16,16,16,16, /* rates 15 2, 15 3 for attack */ +/*18 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */ +}; + + +#define O(a) (a*RATE_STEPS) + +/*note that there is no O(17) in this table - it's directly in the code */ +static const UINT8 eg_rate_select[32+64+32]={ /* Envelope Generator rates (32 + 64 rates + 32 RKS) */ +/* 32 infinite time rates (same as Rate 0) */ +O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18), +O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18), +O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18), +O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18), + +/* rates 00-11 */ +/* +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +*/ +O(18),O(18),O( 0),O( 0), +O( 0),O( 0),O( 2),O( 2), /* Nemesis's tests */ + +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), +O( 0),O( 1),O( 2),O( 3), + +/* rate 12 */ +O( 4),O( 5),O( 6),O( 7), + +/* rate 13 */ +O( 8),O( 9),O(10),O(11), + +/* rate 14 */ +O(12),O(13),O(14),O(15), + +/* rate 15 */ +O(16),O(16),O(16),O(16), + +/* 32 dummy rates (same as 15 3) */ +O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16), +O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16), +O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16), +O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16) + +}; +#undef O + +/*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15*/ +/*shift 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0 */ +/*mask 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0, 0 */ + +#define O(a) (a*1) +static const UINT8 eg_rate_shift[32+64+32]={ /* Envelope Generator counter shifts (32 + 64 rates + 32 RKS) */ +/* 32 infinite time rates */ +/* O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), +O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), +O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), +O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), */ + +/* fixed (should be the same as rate 0, even if it makes no difference since increment value is 0 for these rates) */ +O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11), +O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11), +O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11), +O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11), + +/* rates 00-11 */ +O(11),O(11),O(11),O(11), +O(10),O(10),O(10),O(10), +O( 9),O( 9),O( 9),O( 9), +O( 8),O( 8),O( 8),O( 8), +O( 7),O( 7),O( 7),O( 7), +O( 6),O( 6),O( 6),O( 6), +O( 5),O( 5),O( 5),O( 5), +O( 4),O( 4),O( 4),O( 4), +O( 3),O( 3),O( 3),O( 3), +O( 2),O( 2),O( 2),O( 2), +O( 1),O( 1),O( 1),O( 1), +O( 0),O( 0),O( 0),O( 0), + +/* rate 12 */ +O( 0),O( 0),O( 0),O( 0), + +/* rate 13 */ +O( 0),O( 0),O( 0),O( 0), + +/* rate 14 */ +O( 0),O( 0),O( 0),O( 0), + +/* rate 15 */ +O( 0),O( 0),O( 0),O( 0), + +/* 32 dummy rates (same as 15 3) */ +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), +O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0) + +}; +#undef O + +static const UINT8 dt_tab[4 * 32]={ +/* this is YM2151 and YM2612 phase increment data (in 10.10 fixed point format)*/ +/* FD=0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* FD=1 */ + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, + 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8, +/* FD=2 */ + 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, + 5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16, +/* FD=3 */ + 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, + 8 , 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22 +}; + + +/* OPN key frequency number -> key code follow table */ +/* fnum higher 4bit -> keycode lower 2bit */ +static const UINT8 opn_fktable[16] = {0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3}; + + +/* 8 LFO speed parameters */ +/* each value represents number of samples that one LFO level will last for */ +static const UINT32 lfo_samples_per_step[8] = {108, 77, 71, 67, 62, 44, 8, 5}; + + +/*There are 4 different LFO AM depths available, they are: + 0 dB, 1.4 dB, 5.9 dB, 11.8 dB + Here is how it is generated (in EG steps): + + 11.8 dB = 0, 2, 4, 6, 8, 10,12,14,16...126,126,124,122,120,118,....4,2,0 + 5.9 dB = 0, 1, 2, 3, 4, 5, 6, 7, 8....63, 63, 62, 61, 60, 59,.....2,1,0 + 1.4 dB = 0, 0, 0, 0, 1, 1, 1, 1, 2,...15, 15, 15, 15, 14, 14,.....0,0,0 + + (1.4 dB is loosing precision as you can see) + + It's implemented as generator from 0..126 with step 2 then a shift + right N times, where N is: + 8 for 0 dB + 3 for 1.4 dB + 1 for 5.9 dB + 0 for 11.8 dB +*/ +static const UINT8 lfo_ams_depth_shift[4] = {8, 3, 1, 0}; + + + +/*There are 8 different LFO PM depths available, they are: + 0, 3.4, 6.7, 10, 14, 20, 40, 80 (cents) + + Modulation level at each depth depends on F-NUMBER bits: 4,5,6,7,8,9,10 + (bits 8,9,10 = FNUM MSB from OCT/FNUM register) + + Here we store only first quarter (positive one) of full waveform. + Full table (lfo_pm_table) containing all 128 waveforms is build + at run (init) time. + + One value in table below represents 4 (four) basic LFO steps + (1 PM step = 4 AM steps). + + For example: + at LFO SPEED=0 (which is 108 samples per basic LFO step) + one value from "lfo_pm_output" table lasts for 432 consecutive + samples (4*108=432) and one full LFO waveform cycle lasts for 13824 + samples (32*432=13824; 32 because we store only a quarter of whole + waveform in the table below) +*/ +static const UINT8 lfo_pm_output[7*8][8]={ +/* 7 bits meaningful (of F-NUMBER), 8 LFO output levels per one depth (out of 32), 8 LFO depths */ +/* FNUM BIT 4: 000 0001xxxx */ +/* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 5 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 6 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 7 */ {0, 0, 0, 0, 1, 1, 1, 1}, + +/* FNUM BIT 5: 000 0010xxxx */ +/* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 5 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 6 */ {0, 0, 0, 0, 1, 1, 1, 1}, +/* DEPTH 7 */ {0, 0, 1, 1, 2, 2, 2, 3}, + +/* FNUM BIT 6: 000 0100xxxx */ +/* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 1}, +/* DEPTH 5 */ {0, 0, 0, 0, 1, 1, 1, 1}, +/* DEPTH 6 */ {0, 0, 1, 1, 2, 2, 2, 3}, +/* DEPTH 7 */ {0, 0, 2, 3, 4, 4, 5, 6}, + +/* FNUM BIT 7: 000 1000xxxx */ +/* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 1, 1}, +/* DEPTH 3 */ {0, 0, 0, 0, 1, 1, 1, 1}, +/* DEPTH 4 */ {0, 0, 0, 1, 1, 1, 1, 2}, +/* DEPTH 5 */ {0, 0, 1, 1, 2, 2, 2, 3}, +/* DEPTH 6 */ {0, 0, 2, 3, 4, 4, 5, 6}, +/* DEPTH 7 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc}, + +/* FNUM BIT 8: 001 0000xxxx */ +/* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 1 */ {0, 0, 0, 0, 1, 1, 1, 1}, +/* DEPTH 2 */ {0, 0, 0, 1, 1, 1, 2, 2}, +/* DEPTH 3 */ {0, 0, 1, 1, 2, 2, 3, 3}, +/* DEPTH 4 */ {0, 0, 1, 2, 2, 2, 3, 4}, +/* DEPTH 5 */ {0, 0, 2, 3, 4, 4, 5, 6}, +/* DEPTH 6 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc}, +/* DEPTH 7 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18}, + +/* FNUM BIT 9: 010 0000xxxx */ +/* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 1 */ {0, 0, 0, 0, 2, 2, 2, 2}, +/* DEPTH 2 */ {0, 0, 0, 2, 2, 2, 4, 4}, +/* DEPTH 3 */ {0, 0, 2, 2, 4, 4, 6, 6}, +/* DEPTH 4 */ {0, 0, 2, 4, 4, 4, 6, 8}, +/* DEPTH 5 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc}, +/* DEPTH 6 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18}, +/* DEPTH 7 */ {0, 0,0x10,0x18,0x20,0x20,0x28,0x30}, + +/* FNUM BIT10: 100 0000xxxx */ +/* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0}, +/* DEPTH 1 */ {0, 0, 0, 0, 4, 4, 4, 4}, +/* DEPTH 2 */ {0, 0, 0, 4, 4, 4, 8, 8}, +/* DEPTH 3 */ {0, 0, 4, 4, 8, 8, 0xc, 0xc}, +/* DEPTH 4 */ {0, 0, 4, 8, 8, 8, 0xc,0x10}, +/* DEPTH 5 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18}, +/* DEPTH 6 */ {0, 0,0x10,0x18,0x20,0x20,0x28,0x30}, +/* DEPTH 7 */ {0, 0,0x20,0x30,0x40,0x40,0x50,0x60}, + +}; + +/* all 128 LFO PM waveforms */ +static INT32 lfo_pm_table[128*8*32]; /* 128 combinations of 7 bits meaningful (of F-NUMBER), 8 LFO depths, 32 LFO output levels per one depth */ + +/* register number to channel number , slot offset */ +#define OPN_CHAN(N) (N&3) +#define OPN_SLOT(N) ((N>>2)&3) + +/* slot number */ +#define SLOT1 0 +#define SLOT2 2 +#define SLOT3 1 +#define SLOT4 3 + +/* struct describing a single operator (SLOT) */ +typedef struct +{ + INT32 *DT; /* detune :dt_tab[DT] */ + UINT8 KSR; /* key scale rate :3-KSR */ + UINT32 ar; /* attack rate */ + UINT32 d1r; /* decay rate */ + UINT32 d2r; /* sustain rate */ + UINT32 rr; /* release rate */ + UINT8 ksr; /* key scale rate :kcode>>(3-KSR) */ + UINT32 mul; /* multiple :ML_TABLE[ML] */ + + /* Phase Generator */ + UINT32 phase; /* phase counter */ + INT32 Incr; /* phase step */ + + /* Envelope Generator */ + UINT8 state; /* phase type */ + UINT32 tl; /* total level: TL << 3 */ + INT32 volume; /* envelope counter */ + UINT32 sl; /* sustain level:sl_table[SL] */ + UINT32 vol_out; /* current output from EG circuit (without AM from LFO) */ + + UINT8 eg_sh_ar; /* (attack state) */ + UINT8 eg_sel_ar; /* (attack state) */ + UINT8 eg_sh_d1r; /* (decay state) */ + UINT8 eg_sel_d1r; /* (decay state) */ + UINT8 eg_sh_d2r; /* (sustain state) */ + UINT8 eg_sel_d2r; /* (sustain state) */ + UINT8 eg_sh_rr; /* (release state) */ + UINT8 eg_sel_rr; /* (release state) */ + + UINT8 ssg; /* SSG-EG waveform */ + UINT8 ssgn; /* SSG-EG negated output */ + + UINT8 key; /* 0=last key was KEY OFF, 1=KEY ON */ + + /* LFO */ + UINT32 AMmask; /* AM enable flag */ + +} FM_SLOT; + +typedef struct +{ + FM_SLOT SLOT[4]; /* four SLOTs (operators) */ + + UINT8 ALGO; /* algorithm */ + UINT8 FB; /* feedback shift */ + INT32 op1_out[2]; /* op1 output for feedback */ + + INT32 *connect1; /* SLOT1 output pointer */ + INT32 *connect3; /* SLOT3 output pointer */ + INT32 *connect2; /* SLOT2 output pointer */ + INT32 *connect4; /* SLOT4 output pointer */ + + INT32 *mem_connect; /* where to put the delayed sample (MEM) */ + INT32 mem_value; /* delayed sample (MEM) value */ + + INT32 pms; /* channel PMS */ + UINT8 ams; /* channel AMS */ + + UINT32 fc; /* fnum,blk */ + UINT8 kcode; /* key code */ + UINT32 block_fnum; /* blk/fnum value (for LFO PM calculations) */ +} FM_CH; + + +typedef struct +{ + UINT16 address; /* address register */ + UINT8 status; /* status flag */ + UINT32 mode; /* mode CSM / 3SLOT */ + UINT8 fn_h; /* freq latch */ + INT32 TA; /* timer a value */ + INT32 TAL; /* timer a base */ + INT32 TAC; /* timer a counter */ + INT32 TB; /* timer b value */ + INT32 TBL; /* timer b base */ + INT32 TBC; /* timer b counter */ + INT32 dt_tab[8][32]; /* DeTune table */ + +} FM_ST; + + +/***********************************************************/ +/* OPN unit */ +/***********************************************************/ + +/* OPN 3slot struct */ +typedef struct +{ + UINT32 fc[3]; /* fnum3,blk3: calculated */ + UINT8 fn_h; /* freq3 latch */ + UINT8 kcode[3]; /* key code */ + UINT32 block_fnum[3]; /* current fnum value for this slot (can be different betweeen slots of one channel in 3slot mode) */ + UINT8 key_csm; /* CSM mode Key-ON flag */ + +} FM_3SLOT; + +/* OPN/A/B common state */ +typedef struct +{ + FM_ST ST; /* general state */ + FM_3SLOT SL3; /* 3 slot mode state */ + unsigned int pan[6*2]; /* fm channels output masks (0xffffffff = enable) */ + + /* EG */ + UINT32 eg_cnt; /* global envelope generator counter */ + UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/144/3 */ + + /* LFO */ + UINT8 lfo_cnt; /* current LFO phase (out of 128) */ + UINT32 lfo_timer; /* current LFO phase runs at LFO frequency */ + UINT32 lfo_timer_overflow; /* LFO timer overflows every N samples (depends on LFO frequency) */ + UINT32 LFO_AM; /* current LFO AM step */ + UINT32 LFO_PM; /* current LFO PM step */ + +} FM_OPN; + +/***********************************************************/ +/* YM2612 chip */ +/***********************************************************/ +typedef struct +{ + FM_CH CH[6]; /* channel state */ + UINT8 dacen; /* DAC mode */ + INT32 dacout; /* DAC output */ + FM_OPN OPN; /* OPN state */ + +} YM2612; + +/* emulated chip */ +static YM2612 ym2612; + +/* current chip state */ +static INT32 m2,c1,c2; /* Phase Modulation input for operators 2,3,4 */ +static INT32 mem; /* one sample delay memory */ +static INT32 out_fm[8]; /* outputs of working channels */ +static UINT32 bitmask; /* working channels output bitmasking (DAC quantization) */ + + +INLINE void FM_KEYON(FM_CH *CH , int s ) +{ + FM_SLOT *SLOT = &CH->SLOT[s]; + + if (!SLOT->key && !ym2612.OPN.SL3.key_csm) + { + /* restart Phase Generator */ + SLOT->phase = 0; + + /* reset SSG-EG inversion flag */ + SLOT->ssgn = 0; + + if ((SLOT->ar + SLOT->ksr) < 94 /*32+62*/) + { + SLOT->state = (SLOT->volume <= MIN_ATT_INDEX) ? ((SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC) : EG_ATT; + } + else + { + /* force attenuation level to 0 */ + SLOT->volume = MIN_ATT_INDEX; + + /* directly switch to Decay (or Sustain) */ + SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC; + } + + /* recalculate EG output */ + if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04))) + SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl; + else + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + } + + SLOT->key = 1; +} + +INLINE void FM_KEYOFF(FM_CH *CH , int s ) +{ + FM_SLOT *SLOT = &CH->SLOT[s]; + + if (SLOT->key && !ym2612.OPN.SL3.key_csm) + { + if (SLOT->state>EG_REL) + { + SLOT->state = EG_REL; /* phase -> Release */ + + /* SSG-EG specific update */ + if (SLOT->ssg&0x08) + { + /* convert EG attenuation level */ + if (SLOT->ssgn ^ (SLOT->ssg&0x04)) + SLOT->volume = (0x200 - SLOT->volume); + + /* force EG attenuation level */ + if (SLOT->volume >= 0x200) + { + SLOT->volume = MAX_ATT_INDEX; + SLOT->state = EG_OFF; + } + + /* recalculate EG output */ + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + } + } + } + + SLOT->key = 0; +} + +INLINE void FM_KEYON_CSM(FM_CH *CH , int s ) +{ + FM_SLOT *SLOT = &CH->SLOT[s]; + + if (!SLOT->key && !ym2612.OPN.SL3.key_csm) + { + /* restart Phase Generator */ + SLOT->phase = 0; + + /* reset SSG-EG inversion flag */ + SLOT->ssgn = 0; + + if ((SLOT->ar + SLOT->ksr) < 94 /*32+62*/) + { + SLOT->state = (SLOT->volume <= MIN_ATT_INDEX) ? ((SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC) : EG_ATT; + } + else + { + /* force attenuation level to 0 */ + SLOT->volume = MIN_ATT_INDEX; + + /* directly switch to Decay (or Sustain) */ + SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC; + } + + /* recalculate EG output */ + if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04))) + SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl; + else + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + } +} + +INLINE void FM_KEYOFF_CSM(FM_CH *CH , int s ) +{ + FM_SLOT *SLOT = &CH->SLOT[s]; + if (!SLOT->key) + { + if (SLOT->state>EG_REL) + { + SLOT->state = EG_REL; /* phase -> Release */ + + /* SSG-EG specific update */ + if (SLOT->ssg&0x08) + { + /* convert EG attenuation level */ + if (SLOT->ssgn ^ (SLOT->ssg&0x04)) + SLOT->volume = (0x200 - SLOT->volume); + + /* force EG attenuation level */ + if (SLOT->volume >= 0x200) + { + SLOT->volume = MAX_ATT_INDEX; + SLOT->state = EG_OFF; + } + + /* recalculate EG output */ + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + } + } + } +} + +/* CSM Key Controll */ +INLINE void CSMKeyControll(FM_CH *CH) +{ + /* all key ON (verified by Nemesis on real hardware) */ + FM_KEYON_CSM(CH,SLOT1); + FM_KEYON_CSM(CH,SLOT2); + FM_KEYON_CSM(CH,SLOT3); + FM_KEYON_CSM(CH,SLOT4); + ym2612.OPN.SL3.key_csm = 1; +} + +INLINE void INTERNAL_TIMER_A() +{ + if (ym2612.OPN.ST.mode & 0x01) + { + ym2612.OPN.ST.TAC--; + if (ym2612.OPN.ST.TAC <= 0) + { + /* set status (if enabled) */ + if (ym2612.OPN.ST.mode & 0x04) + ym2612.OPN.ST.status |= 0x01; + + /* reload the counter */ + ym2612.OPN.ST.TAC = ym2612.OPN.ST.TAL; + + /* CSM mode auto key on */ + if ((ym2612.OPN.ST.mode & 0xC0) == 0x80) + CSMKeyControll(&ym2612.CH[2]); + } + } +} + +INLINE void INTERNAL_TIMER_B(int step) +{ + if (ym2612.OPN.ST.mode & 0x02) + { + ym2612.OPN.ST.TBC-=step; + if (ym2612.OPN.ST.TBC <= 0) + { + /* set status (if enabled) */ + if (ym2612.OPN.ST.mode & 0x08) + ym2612.OPN.ST.status |= 0x02; + + /* reload the counter */ + if (ym2612.OPN.ST.TBL) + ym2612.OPN.ST.TBC += ym2612.OPN.ST.TBL; + else + ym2612.OPN.ST.TBC = ym2612.OPN.ST.TBL; + } + } +} + +/* OPN Mode Register Write */ +INLINE void set_timers(int v ) +{ + /* b7 = CSM MODE */ + /* b6 = 3 slot mode */ + /* b5 = reset b */ + /* b4 = reset a */ + /* b3 = timer enable b */ + /* b2 = timer enable a */ + /* b1 = load b */ + /* b0 = load a */ + + if ((ym2612.OPN.ST.mode ^ v) & 0xC0) + { + /* phase increment need to be recalculated */ + ym2612.CH[2].SLOT[SLOT1].Incr=-1; + + /* CSM mode disabled and CSM key ON active*/ + if (((v & 0xC0) != 0x80) && ym2612.OPN.SL3.key_csm) + { + /* CSM Mode Key OFF (verified by Nemesis on real hardware) */ + FM_KEYOFF_CSM(&ym2612.CH[2],SLOT1); + FM_KEYOFF_CSM(&ym2612.CH[2],SLOT2); + FM_KEYOFF_CSM(&ym2612.CH[2],SLOT3); + FM_KEYOFF_CSM(&ym2612.CH[2],SLOT4); + ym2612.OPN.SL3.key_csm = 0; + } + } + + /* reload Timers */ + if ((v&1) && !(ym2612.OPN.ST.mode&1)) + ym2612.OPN.ST.TAC = ym2612.OPN.ST.TAL; + if ((v&2) && !(ym2612.OPN.ST.mode&2)) + ym2612.OPN.ST.TBC = ym2612.OPN.ST.TBL; + + /* reset Timers flags */ + ym2612.OPN.ST.status &= (~v >> 4); + + ym2612.OPN.ST.mode = v; +} + +/* set algorithm connection */ +INLINE void setup_connection( FM_CH *CH, int ch ) +{ + INT32 *carrier = &out_fm[ch]; + + INT32 **om1 = &CH->connect1; + INT32 **om2 = &CH->connect3; + INT32 **oc1 = &CH->connect2; + + INT32 **memc = &CH->mem_connect; + + switch( CH->ALGO ){ + case 0: + /* M1---C1---MEM---M2---C2---OUT */ + *om1 = &c1; + *oc1 = &mem; + *om2 = &c2; + *memc= &m2; + break; + case 1: + /* M1------+-MEM---M2---C2---OUT */ + /* C1-+ */ + *om1 = &mem; + *oc1 = &mem; + *om2 = &c2; + *memc= &m2; + break; + case 2: + /* M1-----------------+-C2---OUT */ + /* C1---MEM---M2-+ */ + *om1 = &c2; + *oc1 = &mem; + *om2 = &c2; + *memc= &m2; + break; + case 3: + /* M1---C1---MEM------+-C2---OUT */ + /* M2-+ */ + *om1 = &c1; + *oc1 = &mem; + *om2 = &c2; + *memc= &c2; + break; + case 4: + /* M1---C1-+-OUT */ + /* M2---C2-+ */ + /* MEM: not used */ + *om1 = &c1; + *oc1 = carrier; + *om2 = &c2; + *memc= &mem; /* store it anywhere where it will not be used */ + break; + case 5: + /* +----C1----+ */ + /* M1-+-MEM---M2-+-OUT */ + /* +----C2----+ */ + *om1 = 0; /* special mark */ + *oc1 = carrier; + *om2 = carrier; + *memc= &m2; + break; + case 6: + /* M1---C1-+ */ + /* M2-+-OUT */ + /* C2-+ */ + /* MEM: not used */ + *om1 = &c1; + *oc1 = carrier; + *om2 = carrier; + *memc= &mem; /* store it anywhere where it will not be used */ + break; + case 7: + /* M1-+ */ + /* C1-+-OUT */ + /* M2-+ */ + /* C2-+ */ + /* MEM: not used*/ + *om1 = carrier; + *oc1 = carrier; + *om2 = carrier; + *memc= &mem; /* store it anywhere where it will not be used */ + break; + } + + CH->connect4 = carrier; +} + +/* set detune & multiple */ +INLINE void set_det_mul(FM_CH *CH,FM_SLOT *SLOT,int v) +{ + SLOT->mul = (v&0x0f)? (v&0x0f)*2 : 1; + SLOT->DT = ym2612.OPN.ST.dt_tab[(v>>4)&7]; + CH->SLOT[SLOT1].Incr=-1; +} + +/* set total level */ +INLINE void set_tl(FM_SLOT *SLOT , int v) +{ + SLOT->tl = (v&0x7f)<<(ENV_BITS-7); /* 7bit TL */ + + /* recalculate EG output */ + if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04)) && (SLOT->state > EG_REL)) + SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl; + else + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; +} + +/* set attack rate & key scale */ +INLINE void set_ar_ksr(FM_CH *CH,FM_SLOT *SLOT,int v) +{ + UINT8 old_KSR = SLOT->KSR; + + SLOT->ar = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0; + + SLOT->KSR = 3-(v>>6); + if (SLOT->KSR != old_KSR) + { + CH->SLOT[SLOT1].Incr=-1; + } + + /* Even if it seems unnecessary to do it here, it could happen that KSR and KC */ + /* are modified but the resulted SLOT->ksr value (kc >> SLOT->KSR) remains unchanged. */ + /* In such case, Attack Rate would not be recalculated by "refresh_fc_eg_slot". */ + /* This actually fixes the intro of "The Adventures of Batman & Robin" (Eke-Eke) */ + if ((SLOT->ar + SLOT->ksr) < (32+62)) + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } + else + { + /* verified by Nemesis on real hardware (Attack phase is blocked) */ + SLOT->eg_sh_ar = 0; + SLOT->eg_sel_ar = 18*RATE_STEPS; + } + } + +/* set decay rate */ +INLINE void set_dr(FM_SLOT *SLOT,int v) +{ + SLOT->d1r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0; + + SLOT->eg_sh_d1r = eg_rate_shift [SLOT->d1r + SLOT->ksr]; + SLOT->eg_sel_d1r= eg_rate_select[SLOT->d1r + SLOT->ksr]; + +} + +/* set sustain rate */ +INLINE void set_sr(FM_SLOT *SLOT,int v) +{ + SLOT->d2r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0; + + SLOT->eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr]; + SLOT->eg_sel_d2r= eg_rate_select[SLOT->d2r + SLOT->ksr]; +} + +/* set release rate */ +INLINE void set_sl_rr(FM_SLOT *SLOT,int v) +{ + SLOT->sl = sl_table[ v>>4 ]; + + /* check EG state changes */ + if ((SLOT->state == EG_DEC) && (SLOT->volume >= (INT32)(SLOT->sl))) + SLOT->state = EG_SUS; + + SLOT->rr = 34 + ((v&0x0f)<<2); + + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr]; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr]; +} + +/* advance LFO to next sample */ +INLINE void advance_lfo() +{ + if (ym2612.OPN.lfo_timer_overflow) /* LFO enabled ? */ + { + /* increment LFO timer (every samples) */ + ym2612.OPN.lfo_timer ++; + + /* when LFO is enabled, one level will last for 108, 77, 71, 67, 62, 44, 8 or 5 samples */ + if (ym2612.OPN.lfo_timer >= ym2612.OPN.lfo_timer_overflow) + { + ym2612.OPN.lfo_timer = 0; + + /* There are 128 LFO steps */ + ym2612.OPN.lfo_cnt = ( ym2612.OPN.lfo_cnt + 1 ) & 127; + + /* triangle (inverted) */ + /* AM: from 126 to 0 step -2, 0 to 126 step +2 */ + if (ym2612.OPN.lfo_cnt<64) + ym2612.OPN.LFO_AM = (ym2612.OPN.lfo_cnt ^ 63) << 1; + else + ym2612.OPN.LFO_AM = (ym2612.OPN.lfo_cnt & 63) << 1; + + /* PM works with 4 times slower clock */ + ym2612.OPN.LFO_PM = ym2612.OPN.lfo_cnt >> 2; + } + } +} + + +INLINE void advance_eg_channels(FM_CH *CH, unsigned int eg_cnt) +{ + unsigned int i = 6; /* six channels */ + unsigned int j; + FM_SLOT *SLOT; + + do + { + SLOT = &CH->SLOT[SLOT1]; + j = 4; /* four operators per channel */ + do + { + switch(SLOT->state) + { + case EG_ATT: /* attack phase */ + { + if (!(eg_cnt & ((1<eg_sh_ar)-1))) + { + /* update attenuation level */ + SLOT->volume += (~SLOT->volume * (eg_inc[SLOT->eg_sel_ar + ((eg_cnt>>SLOT->eg_sh_ar)&7)]))>>4; + + /* check phase transition*/ + if (SLOT->volume <= MIN_ATT_INDEX) + { + SLOT->volume = MIN_ATT_INDEX; + SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC; /* special case where SL=0 */ + } + + /* recalculate EG output */ + if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04))) /* SSG-EG Output Inversion */ + SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl; + else + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + } + break; + } + + case EG_DEC: /* decay phase */ + { + if (!(eg_cnt & ((1<eg_sh_d1r)-1))) + { + /* SSG EG type */ + if (SLOT->ssg&0x08) + { + /* update attenuation level */ + if (SLOT->volume < 0x200) + { + SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d1r + ((eg_cnt>>SLOT->eg_sh_d1r)&7)]; + + /* recalculate EG output */ + if (SLOT->ssgn ^ (SLOT->ssg&0x04)) /* SSG-EG Output Inversion */ + SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl; + else + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + } + } + else + { + /* update attenuation level */ + SLOT->volume += eg_inc[SLOT->eg_sel_d1r + ((eg_cnt>>SLOT->eg_sh_d1r)&7)]; + + /* recalculate EG output */ + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + } + + /* check phase transition*/ + if (SLOT->volume >= (INT32)(SLOT->sl)) + SLOT->state = EG_SUS; + } + break; + } + + case EG_SUS: /* sustain phase */ + { + if (!(eg_cnt & ((1<eg_sh_d2r)-1))) + { + /* SSG EG type */ + if (SLOT->ssg&0x08) + { + /* update attenuation level */ + if (SLOT->volume < 0x200) + { + SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d2r + ((eg_cnt>>SLOT->eg_sh_d2r)&7)]; + + /* recalculate EG output */ + if (SLOT->ssgn ^ (SLOT->ssg&0x04)) /* SSG-EG Output Inversion */ + SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl; + else + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + } + } + else + { + /* update attenuation level */ + SLOT->volume += eg_inc[SLOT->eg_sel_d2r + ((eg_cnt>>SLOT->eg_sh_d2r)&7)]; + + /* check phase transition*/ + if ( SLOT->volume >= MAX_ATT_INDEX ) + SLOT->volume = MAX_ATT_INDEX; + /* do not change SLOT->state (verified on real chip) */ + + /* recalculate EG output */ + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + } + } + break; + } + + case EG_REL: /* release phase */ + { + if (!(eg_cnt & ((1<eg_sh_rr)-1))) + { + /* SSG EG type */ + if (SLOT->ssg&0x08) + { + /* update attenuation level */ + if (SLOT->volume < 0x200) + SLOT->volume += 4 * eg_inc[SLOT->eg_sel_rr + ((eg_cnt>>SLOT->eg_sh_rr)&7)]; + + /* check phase transition */ + if (SLOT->volume >= 0x200) + { + SLOT->volume = MAX_ATT_INDEX; + SLOT->state = EG_OFF; + } + } + else + { + /* update attenuation level */ + SLOT->volume += eg_inc[SLOT->eg_sel_rr + ((eg_cnt>>SLOT->eg_sh_rr)&7)]; + + /* check phase transition*/ + if (SLOT->volume >= MAX_ATT_INDEX) + { + SLOT->volume = MAX_ATT_INDEX; + SLOT->state = EG_OFF; + } + } + + /* recalculate EG output */ + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + + } + break; + } + } + + /* next slot */ + SLOT++; + } while (--j); + + /* next channel */ + CH++; + } while (--i); +} + +/* SSG-EG update process */ +/* The behavior is based upon Nemesis tests on real hardware */ +/* This is actually executed before each samples */ +INLINE void update_ssg_eg_channels(FM_CH *CH) +{ + unsigned int i = 6; /* six channels */ + unsigned int j; + FM_SLOT *SLOT; + + do + { + j = 4; /* four operators per channel */ + SLOT = &CH->SLOT[SLOT1]; + + do + { + /* detect SSG-EG transition */ + /* this is not required during release phase as the attenuation has been forced to MAX and output invert flag is not used */ + /* if an Attack Phase is programmed, inversion can occur on each sample */ + if ((SLOT->ssg & 0x08) && (SLOT->volume >= 0x200) && (SLOT->state > EG_REL)) + { + if (SLOT->ssg & 0x01) /* bit 0 = hold SSG-EG */ + { + /* set inversion flag */ + if (SLOT->ssg & 0x02) + SLOT->ssgn = 4; + + /* force attenuation level during decay phases */ + if ((SLOT->state != EG_ATT) && !(SLOT->ssgn ^ (SLOT->ssg & 0x04))) + SLOT->volume = MAX_ATT_INDEX; + } + else /* loop SSG-EG */ + { + /* toggle output inversion flag or reset Phase Generator */ + if (SLOT->ssg & 0x02) + SLOT->ssgn ^= 4; + else + SLOT->phase = 0; + + /* same as Key ON */ + if (SLOT->state != EG_ATT) + { + if ((SLOT->ar + SLOT->ksr) < 94 /*32+62*/) + { + SLOT->state = (SLOT->volume <= MIN_ATT_INDEX) ? ((SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC) : EG_ATT; + } + else + { + /* Attack Rate is maximal: directly switch to Decay or Substain */ + SLOT->volume = MIN_ATT_INDEX; + SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC; + } + } + } + + /* recalculate EG output */ + if (SLOT->ssgn ^ (SLOT->ssg&0x04)) + SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl; + else + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + } + + /* next slot */ + SLOT++; + } while (--j); + + /* next channel */ + CH++; + } while (--i); +} + +INLINE void update_phase_lfo_slot(FM_SLOT *SLOT, INT32 pms, UINT32 block_fnum) +{ + INT32 lfo_fn_table_index_offset = lfo_pm_table[(((block_fnum & 0x7f0) >> 4) << 8) + pms + ym2612.OPN.LFO_PM]; + + if (lfo_fn_table_index_offset) /* LFO phase modulation active */ + { + UINT8 blk; + unsigned int kc, fc; + + /* there are 2048 FNUMs that can be generated using FNUM/BLK registers + but LFO works with one more bit of a precision so we really need 4096 elements */ + block_fnum = block_fnum*2 + lfo_fn_table_index_offset; + blk = (block_fnum&0x7000) >> 12; + block_fnum = block_fnum & 0xfff; + + /* keyscale code */ + kc = (blk<<2) | opn_fktable[block_fnum >> 8]; + + /* (frequency) phase increment counter */ + fc = (((block_fnum << 5) >> (7 - blk)) + SLOT->DT[kc]) & DT_MASK; + + /* update phase */ + SLOT->phase += (fc * SLOT->mul) >> 1; + } + else /* LFO phase modulation = zero */ + { + SLOT->phase += SLOT->Incr; + } +} + +INLINE void update_phase_lfo_channel(FM_CH *CH) +{ + UINT32 block_fnum = CH->block_fnum; + + INT32 lfo_fn_table_index_offset = lfo_pm_table[(((block_fnum & 0x7f0) >> 4) << 8) + CH->pms + ym2612.OPN.LFO_PM]; + + if (lfo_fn_table_index_offset) /* LFO phase modulation active */ + { + UINT8 blk; + unsigned int kc, fc, finc; + + /* there are 2048 FNUMs that can be generated using FNUM/BLK registers + but LFO works with one more bit of a precision so we really need 4096 elements */ + block_fnum = block_fnum*2 + lfo_fn_table_index_offset; + blk = (block_fnum&0x7000) >> 12; + block_fnum = block_fnum & 0xfff; + + /* keyscale code */ + kc = (blk<<2) | opn_fktable[block_fnum >> 8]; + + /* (frequency) phase increment counter */ + fc = (block_fnum << 5) >> (7 - blk); + + /* apply DETUNE & MUL operator specific values */ + finc = (fc + CH->SLOT[SLOT1].DT[kc]) & DT_MASK; + CH->SLOT[SLOT1].phase += (finc*CH->SLOT[SLOT1].mul) >> 1; + + finc = (fc + CH->SLOT[SLOT2].DT[kc]) & DT_MASK; + CH->SLOT[SLOT2].phase += (finc*CH->SLOT[SLOT2].mul) >> 1; + + finc = (fc + CH->SLOT[SLOT3].DT[kc]) & DT_MASK; + CH->SLOT[SLOT3].phase += (finc*CH->SLOT[SLOT3].mul) >> 1; + + finc = (fc + CH->SLOT[SLOT4].DT[kc]) & DT_MASK; + CH->SLOT[SLOT4].phase += (finc*CH->SLOT[SLOT4].mul) >> 1; + } + else /* LFO phase modulation = zero */ + { + CH->SLOT[SLOT1].phase += CH->SLOT[SLOT1].Incr; + CH->SLOT[SLOT2].phase += CH->SLOT[SLOT2].Incr; + CH->SLOT[SLOT3].phase += CH->SLOT[SLOT3].Incr; + CH->SLOT[SLOT4].phase += CH->SLOT[SLOT4].Incr; + } +} + +/* update phase increment and envelope generator */ +INLINE void refresh_fc_eg_slot(FM_SLOT *SLOT , unsigned int fc , unsigned int kc ) +{ + /* add detune value */ + fc += SLOT->DT[kc]; + + /* (frequency) phase overflow (credits to Nemesis) */ + fc &= DT_MASK; + + /* (frequency) phase increment counter */ + SLOT->Incr = (fc * SLOT->mul) >> 1; + + /* ksr */ + kc = kc >> SLOT->KSR; + + if( SLOT->ksr != kc ) + { + SLOT->ksr = kc; + + /* recalculate envelope generator rates */ + if ((SLOT->ar + kc) < (32+62)) + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + kc ]; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + kc ]; + } + else + { + /* verified by Nemesis on real hardware (Attack phase is blocked) */ + SLOT->eg_sh_ar = 0; + SLOT->eg_sel_ar = 18*RATE_STEPS; + } + + SLOT->eg_sh_d1r = eg_rate_shift [SLOT->d1r + kc]; + SLOT->eg_sel_d1r= eg_rate_select[SLOT->d1r + kc]; + + SLOT->eg_sh_d2r = eg_rate_shift [SLOT->d2r + kc]; + SLOT->eg_sel_d2r= eg_rate_select[SLOT->d2r + kc]; + + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + kc]; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + kc]; + } +} + +/* update phase increment counters */ +INLINE void refresh_fc_eg_chan(FM_CH *CH ) +{ + if( CH->SLOT[SLOT1].Incr==-1) + { + int fc = CH->fc; + int kc = CH->kcode; + refresh_fc_eg_slot(&CH->SLOT[SLOT1] , fc , kc ); + refresh_fc_eg_slot(&CH->SLOT[SLOT2] , fc , kc ); + refresh_fc_eg_slot(&CH->SLOT[SLOT3] , fc , kc ); + refresh_fc_eg_slot(&CH->SLOT[SLOT4] , fc , kc ); + } +} + +#define volume_calc(OP) ((OP)->vol_out + (AM & (OP)->AMmask)) + +INLINE signed int op_calc(UINT32 phase, unsigned int env, unsigned int pm) +{ + UINT32 p = (env<<3) + sin_tab[ ( (phase >> SIN_BITS) + (pm >> 1) ) & SIN_MASK ]; + + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; +} + +INLINE signed int op_calc1(UINT32 phase, unsigned int env, unsigned int pm) +{ + UINT32 p = (env<<3) + sin_tab[ ( (phase + pm ) >> SIN_BITS ) & SIN_MASK ]; + + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; +} + +INLINE void chan_calc(FM_CH *CH, int num) +{ + do + { + UINT32 AM = ym2612.OPN.LFO_AM >> CH->ams; + unsigned int eg_out = volume_calc(&CH->SLOT[SLOT1]); + + m2 = c1 = c2 = mem = 0; + + *CH->mem_connect = CH->mem_value; /* restore delayed sample (MEM) value to m2 or c2 */ + { + INT32 out = CH->op1_out[0] + CH->op1_out[1]; + CH->op1_out[0] = CH->op1_out[1]; + + if( !CH->connect1 ){ + /* algorithm 5 */ + mem = c1 = c2 = CH->op1_out[0]; + }else{ + /* other algorithms */ + *CH->connect1 += CH->op1_out[0]; + } + + CH->op1_out[1] = 0; + if( eg_out < ENV_QUIET ) /* SLOT 1 */ + { + if (!CH->FB) + out=0; + + CH->op1_out[1] = op_calc1(CH->SLOT[SLOT1].phase, eg_out, (out<FB) ); + } + } + + eg_out = volume_calc(&CH->SLOT[SLOT3]); + if( eg_out < ENV_QUIET ) /* SLOT 3 */ + *CH->connect3 += op_calc(CH->SLOT[SLOT3].phase, eg_out, m2); + + eg_out = volume_calc(&CH->SLOT[SLOT2]); + if( eg_out < ENV_QUIET ) /* SLOT 2 */ + *CH->connect2 += op_calc(CH->SLOT[SLOT2].phase, eg_out, c1); + + eg_out = volume_calc(&CH->SLOT[SLOT4]); + if( eg_out < ENV_QUIET ) /* SLOT 4 */ + *CH->connect4 += op_calc(CH->SLOT[SLOT4].phase, eg_out, c2); + + + /* store current MEM */ + CH->mem_value = mem; + + /* update phase counters AFTER output calculations */ + if(CH->pms) + { + /* add support for 3 slot mode */ + if ((ym2612.OPN.ST.mode & 0xC0) && (CH == &ym2612.CH[2])) + { + update_phase_lfo_slot(&CH->SLOT[SLOT1], CH->pms, ym2612.OPN.SL3.block_fnum[1]); + update_phase_lfo_slot(&CH->SLOT[SLOT2], CH->pms, ym2612.OPN.SL3.block_fnum[2]); + update_phase_lfo_slot(&CH->SLOT[SLOT3], CH->pms, ym2612.OPN.SL3.block_fnum[0]); + update_phase_lfo_slot(&CH->SLOT[SLOT4], CH->pms, CH->block_fnum); + } + else + { + update_phase_lfo_channel(CH); + } + } + else /* no LFO phase modulation */ + { + CH->SLOT[SLOT1].phase += CH->SLOT[SLOT1].Incr; + CH->SLOT[SLOT2].phase += CH->SLOT[SLOT2].Incr; + CH->SLOT[SLOT3].phase += CH->SLOT[SLOT3].Incr; + CH->SLOT[SLOT4].phase += CH->SLOT[SLOT4].Incr; + } + + /* next channel */ + CH++; + } while (--num); +} + +/* write a OPN mode register 0x20-0x2f */ +INLINE void OPNWriteMode(int r, int v) +{ + UINT8 c; + FM_CH *CH; + + switch(r){ + case 0x21: /* Test */ + break; + + case 0x22: /* LFO FREQ (YM2608/YM2610/YM2610B/ym2612) */ + if (v&8) /* LFO enabled ? */ + { + ym2612.OPN.lfo_timer_overflow = lfo_samples_per_step[v&7]; + } + else + { + /* hold LFO waveform in reset state */ + ym2612.OPN.lfo_timer_overflow = 0; + ym2612.OPN.lfo_timer = 0; + ym2612.OPN.lfo_cnt = 0; + ym2612.OPN.LFO_PM = 0; + ym2612.OPN.LFO_AM = 126; + } + break; + case 0x24: /* timer A High 8*/ + ym2612.OPN.ST.TA = (ym2612.OPN.ST.TA & 0x03)|(((int)v)<<2); + ym2612.OPN.ST.TAL = 1024 - ym2612.OPN.ST.TA; + break; + case 0x25: /* timer A Low 2*/ + ym2612.OPN.ST.TA = (ym2612.OPN.ST.TA & 0x3fc)|(v&3); + ym2612.OPN.ST.TAL = 1024 - ym2612.OPN.ST.TA; + break; + case 0x26: /* timer B */ + ym2612.OPN.ST.TB = v; + ym2612.OPN.ST.TBL = (256 - v) << 4; + break; + case 0x27: /* mode, timer control */ + set_timers(v); + break; + case 0x28: /* key on / off */ + c = v & 0x03; + if( c == 3 ) break; + if (v&0x04) c+=3; /* CH 4-6 */ + CH = &ym2612.CH[c]; + + if (v&0x10) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1); + if (v&0x20) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2); + if (v&0x40) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3); + if (v&0x80) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4); + break; + } +} + +/* write a OPN register (0x30-0xff) */ +INLINE void OPNWriteReg(int r, int v) +{ + FM_CH *CH; + FM_SLOT *SLOT; + + UINT8 c = OPN_CHAN(r); + + if (c == 3) return; /* 0xX3,0xX7,0xXB,0xXF */ + + if (r >= 0x100) c+=3; + + CH = &ym2612.CH[c]; + + SLOT = &(CH->SLOT[OPN_SLOT(r)]); + + switch( r & 0xf0 ) { + case 0x30: /* DET , MUL */ + set_det_mul(CH,SLOT,v); + break; + + case 0x40: /* TL */ + set_tl(SLOT,v); + break; + + case 0x50: /* KS, AR */ + set_ar_ksr(CH,SLOT,v); + break; + + case 0x60: /* bit7 = AM ENABLE, DR */ + set_dr(SLOT,v); + SLOT->AMmask = (v&0x80) ? ~0 : 0; + break; + + case 0x70: /* SR */ + set_sr(SLOT,v); + break; + + case 0x80: /* SL, RR */ + set_sl_rr(SLOT,v); + break; + + case 0x90: /* SSG-EG */ + SLOT->ssg = v&0x0f; + + /* recalculate EG output */ + if (SLOT->state > EG_REL) + { + if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04))) + SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl; + else + SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl; + } + + /* SSG-EG envelope shapes : + + E AtAlH + 1 0 0 0 \\\\ + + 1 0 0 1 \___ + + 1 0 1 0 \/\/ + ___ + 1 0 1 1 \ + + 1 1 0 0 //// + ___ + 1 1 0 1 / + + 1 1 1 0 /\/\ + + 1 1 1 1 /___ + + + E = SSG-EG enable + + + The shapes are generated using Attack, Decay and Sustain phases. + + Each single character in the diagrams above represents this whole + sequence: + + - when KEY-ON = 1, normal Attack phase is generated (*without* any + difference when compared to normal mode), + + - later, when envelope level reaches minimum level (max volume), + the EG switches to Decay phase (which works with bigger steps + when compared to normal mode - see below), + + - later when envelope level passes the SL level, + the EG swithes to Sustain phase (which works with bigger steps + when compared to normal mode - see below), + + - finally when envelope level reaches maximum level (min volume), + the EG switches to Attack phase again (depends on actual waveform). + + Important is that when switch to Attack phase occurs, the phase counter + of that operator will be zeroed-out (as in normal KEY-ON) but not always. + (I havent found the rule for that - perhaps only when the output level is low) + + The difference (when compared to normal Envelope Generator mode) is + that the resolution in Decay and Sustain phases is 4 times lower; + this results in only 256 steps instead of normal 1024. + In other words: + when SSG-EG is disabled, the step inside of the EG is one, + when SSG-EG is enabled, the step is four (in Decay and Sustain phases). + + Times between the level changes are the same in both modes. + + + Important: + Decay 1 Level (so called SL) is compared to actual SSG-EG output, so + it is the same in both SSG and no-SSG modes, with this exception: + + when the SSG-EG is enabled and is generating raising levels + (when the EG output is inverted) the SL will be found at wrong level !!! + For example, when SL=02: + 0 -6 = -6dB in non-inverted EG output + 96-6 = -90dB in inverted EG output + Which means that EG compares its level to SL as usual, and that the + output is simply inverted afterall. + + + The Yamaha's manuals say that AR should be set to 0x1f (max speed). + That is not necessary, but then EG will be generating Attack phase. + + */ + + + break; + + case 0xa0: + switch( OPN_SLOT(r) ){ + case 0: /* 0xa0-0xa2 : FNUM1 */ + { + UINT32 fn = (((UINT32)((ym2612.OPN.ST.fn_h)&7))<<8) + v; + UINT8 blk = ym2612.OPN.ST.fn_h>>3; + /* keyscale code */ + CH->kcode = (blk<<2) | opn_fktable[fn >> 7]; + /* phase increment counter */ + CH->fc = (fn << 6) >> (7 - blk); + + /* store fnum in clear form for LFO PM calculations */ + CH->block_fnum = (blk<<11) | fn; + + CH->SLOT[SLOT1].Incr=-1; + break; + } + case 1: /* 0xa4-0xa6 : FNUM2,BLK */ + ym2612.OPN.ST.fn_h = v&0x3f; + break; + case 2: /* 0xa8-0xaa : 3CH FNUM1 */ + if(r < 0x100) + { + UINT32 fn = (((UINT32)(ym2612.OPN.SL3.fn_h&7))<<8) + v; + UINT8 blk = ym2612.OPN.SL3.fn_h>>3; + /* keyscale code */ + ym2612.OPN.SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7]; + /* phase increment counter */ + ym2612.OPN.SL3.fc[c] = (fn << 6) >> (7 - blk); + ym2612.OPN.SL3.block_fnum[c] = (blk<<11) | fn; + ym2612.CH[2].SLOT[SLOT1].Incr=-1; + } + break; + case 3: /* 0xac-0xae : 3CH FNUM2,BLK */ + if(r < 0x100) + ym2612.OPN.SL3.fn_h = v&0x3f; + break; + } + break; + + case 0xb0: + switch( OPN_SLOT(r) ){ + case 0: /* 0xb0-0xb2 : FB,ALGO */ + { + CH->ALGO = v&7; + CH->FB = (v>>3)&7; + setup_connection( CH, c ); + break; + } + case 1: /* 0xb4-0xb6 : L , R , AMS , PMS */ + /* b0-2 PMS */ + CH->pms = (v & 7) * 32; /* CH->pms = PM depth * 32 (index in lfo_pm_table) */ + + /* b4-5 AMS */ + CH->ams = lfo_ams_depth_shift[(v>>4) & 0x03]; + + /* PAN : b7 = L, b6 = R */ + ym2612.OPN.pan[ c*2 ] = (v & 0x80) ? bitmask : 0; + ym2612.OPN.pan[ c*2+1 ] = (v & 0x40) ? bitmask : 0; + break; + } + break; + } +} + +static void reset_channels(FM_CH *CH , int num ) +{ + int c,s; + + for( c = 0 ; c < num ; c++ ) + { + CH[c].mem_value = 0; + CH[c].op1_out[0] = 0; + CH[c].op1_out[1] = 0; + for(s = 0 ; s < 4 ; s++ ) + { + CH[c].SLOT[s].Incr = -1; + CH[c].SLOT[s].key = 0; + CH[c].SLOT[s].phase = 0; + CH[c].SLOT[s].ssgn = 0; + CH[c].SLOT[s].state = EG_OFF; + CH[c].SLOT[s].volume = MAX_ATT_INDEX; + CH[c].SLOT[s].vol_out = MAX_ATT_INDEX; + } + } +} + +/* initialize generic tables */ +static void init_tables(void) +{ + signed int d,i,x; + signed int n; + double o,m; + + /* build Linear Power Table */ + for (x=0; x>= 4; /* 12 bits here */ + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + /* 11 bits here (rounded) */ + n <<= 2; /* 13 bits here (as in real chip) */ + + /* 14 bits (with sign bit) */ + tl_tab[ x*2 + 0 ] = n; + tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ]; + + /* one entry in the 'Power' table use the following format, xxxxxyyyyyyyys with: */ + /* s = sign bit */ + /* yyyyyyyy = 8-bits decimal part (0-TL_RES_LEN) */ + /* xxxxx = 5-bits integer 'shift' value (0-31) but, since Power table output is 13 bits, */ + /* any value above 13 (included) would be discarded. */ + for (i=1; i<13; i++) + { + tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; + tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; + } + } + + /* build Logarithmic Sinus table */ + for (i=0; i0.0) + o = 8*log(1.0/m)/log(2); /* convert to 'decibels' */ + else + o = 8*log(-1.0/m)/log(2); /* convert to 'decibels' */ + + o = o / (ENV_STEP/4); + + n = (int)(2.0*o); + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + + /* 13-bits (8.5) value is formatted for above 'Power' table */ + sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); + } + + /* build LFO PM modulation table */ + for(i = 0; i < 8; i++) /* 8 PM depths */ + { + UINT8 fnum; + for (fnum=0; fnum<128; fnum++) /* 7 bits meaningful of F-NUMBER */ + { + UINT8 value; + UINT8 step; + UINT32 offset_depth = i; + UINT32 offset_fnum_bit; + UINT32 bit_tmp; + + for (step=0; step<8; step++) + { + value = 0; + for (bit_tmp=0; bit_tmp<7; bit_tmp++) /* 7 bits */ + { + if (fnum & (1<= 0xb4 ; i-- ) + { + OPNWriteReg(i ,0xc0); + OPNWriteReg(i|0x100,0xc0); + } + for(i = 0xb2 ; i >= 0x30 ; i-- ) + { + OPNWriteReg(i ,0); + OPNWriteReg(i|0x100,0); + } +} + +/* ym2612 write */ +/* n = number */ +/* a = address */ +/* v = value */ +void YM2612Write(unsigned int a, unsigned int v) +{ + v &= 0xff; /* adjust to 8 bit bus */ + + switch( a ) + { + case 0: /* address port 0 */ + ym2612.OPN.ST.address = v; + break; + + case 2: /* address port 1 */ + ym2612.OPN.ST.address = v | 0x100; + break; + + default: /* data port */ + { + int addr = ym2612.OPN.ST.address; /* verified by Nemesis on real YM2612 */ + switch( addr & 0x1f0 ) + { + case 0x20: /* 0x20-0x2f Mode */ + switch( addr ) + { + case 0x2a: /* DAC data (ym2612) */ + ym2612.dacout = ((int)v - 0x80) << 6; /* convert to 14-bit output */ + break; + case 0x2b: /* DAC Sel (ym2612) */ + /* b7 = dac enable */ + ym2612.dacen = v & 0x80; + break; + default: /* OPN section */ + /* write register */ + OPNWriteMode(addr,v); + } + break; + default: /* 0x30-0xff OPN section */ + /* write register */ + OPNWriteReg(addr,v); + } + break; + } + } +} + +unsigned int YM2612Read(void) +{ + return ym2612.OPN.ST.status & 0xff; +} + +/* Generate samples for ym2612 */ +void YM2612Update(int *buffer, int length) +{ + int i; + int lt,rt; + + /* refresh PG increments and EG rates if required */ + refresh_fc_eg_chan(&ym2612.CH[0]); + refresh_fc_eg_chan(&ym2612.CH[1]); + + if (!(ym2612.OPN.ST.mode & 0xC0)) + { + refresh_fc_eg_chan(&ym2612.CH[2]); + } + else + { + /* 3SLOT MODE (operator order is 0,1,3,2) */ + if(ym2612.CH[2].SLOT[SLOT1].Incr==-1) + { + refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT1] , ym2612.OPN.SL3.fc[1] , ym2612.OPN.SL3.kcode[1] ); + refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT2] , ym2612.OPN.SL3.fc[2] , ym2612.OPN.SL3.kcode[2] ); + refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT3] , ym2612.OPN.SL3.fc[0] , ym2612.OPN.SL3.kcode[0] ); + refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT4] , ym2612.CH[2].fc , ym2612.CH[2].kcode ); + } + } + + refresh_fc_eg_chan(&ym2612.CH[3]); + refresh_fc_eg_chan(&ym2612.CH[4]); + refresh_fc_eg_chan(&ym2612.CH[5]); + + /* buffering */ + for(i=0; i < length ; i++) + { + /* clear outputs */ + out_fm[0] = 0; + out_fm[1] = 0; + out_fm[2] = 0; + out_fm[3] = 0; + out_fm[4] = 0; + out_fm[5] = 0; + + /* update SSG-EG output */ + update_ssg_eg_channels(&ym2612.CH[0]); + + /* calculate FM */ + if (!ym2612.dacen) + { + chan_calc(&ym2612.CH[0],6); + } + else + { + /* DAC Mode */ + out_fm[5] = ym2612.dacout; + chan_calc(&ym2612.CH[0],5); + } + + /* advance LFO */ + advance_lfo(); + + /* advance envelope generator */ + ym2612.OPN.eg_timer ++; + + /* EG is updated every 3 samples */ + if (ym2612.OPN.eg_timer >= 3) + { + ym2612.OPN.eg_timer = 0; + ym2612.OPN.eg_cnt++; + advance_eg_channels(&ym2612.CH[0], ym2612.OPN.eg_cnt); + } + + /* 14-bit accumulator channels outputs (range is -8192;+8192) */ + if (out_fm[0] > 8192) out_fm[0] = 8192; + else if (out_fm[0] < -8192) out_fm[0] = -8192; + if (out_fm[1] > 8192) out_fm[1] = 8192; + else if (out_fm[1] < -8192) out_fm[1] = -8192; + if (out_fm[2] > 8192) out_fm[2] = 8192; + else if (out_fm[2] < -8192) out_fm[2] = -8192; + if (out_fm[3] > 8192) out_fm[3] = 8192; + else if (out_fm[3] < -8192) out_fm[3] = -8192; + if (out_fm[4] > 8192) out_fm[4] = 8192; + else if (out_fm[4] < -8192) out_fm[4] = -8192; + if (out_fm[5] > 8192) out_fm[5] = 8192; + else if (out_fm[5] < -8192) out_fm[5] = -8192; + + /* stereo DAC channels outputs mixing */ + lt = ((out_fm[0]) & ym2612.OPN.pan[0]); + rt = ((out_fm[0]) & ym2612.OPN.pan[1]); + lt += ((out_fm[1]) & ym2612.OPN.pan[2]); + rt += ((out_fm[1]) & ym2612.OPN.pan[3]); + lt += ((out_fm[2]) & ym2612.OPN.pan[4]); + rt += ((out_fm[2]) & ym2612.OPN.pan[5]); + lt += ((out_fm[3]) & ym2612.OPN.pan[6]); + rt += ((out_fm[3]) & ym2612.OPN.pan[7]); + lt += ((out_fm[4]) & ym2612.OPN.pan[8]); + rt += ((out_fm[4]) & ym2612.OPN.pan[9]); + lt += ((out_fm[5]) & ym2612.OPN.pan[10]); + rt += ((out_fm[5]) & ym2612.OPN.pan[11]); + + /* buffering */ + *buffer++ = lt; + *buffer++ = rt; + + /* CSM mode: if CSM Key ON has occured, CSM Key OFF need to be sent */ + /* only if Timer A does not overflow again (i.e CSM Key ON not set again) */ + ym2612.OPN.SL3.key_csm <<= 1; + + /* timer A control */ + INTERNAL_TIMER_A(); + + /* CSM Mode Key ON still disabled */ + if (ym2612.OPN.SL3.key_csm & 2) + { + /* CSM Mode Key OFF (verified by Nemesis on real hardware) */ + FM_KEYOFF_CSM(&ym2612.CH[2],SLOT1); + FM_KEYOFF_CSM(&ym2612.CH[2],SLOT2); + FM_KEYOFF_CSM(&ym2612.CH[2],SLOT3); + FM_KEYOFF_CSM(&ym2612.CH[2],SLOT4); + ym2612.OPN.SL3.key_csm = 0; + } + } + + /* timer B control */ + INTERNAL_TIMER_B(length); +} + +void YM2612Config(unsigned char dac_bits) +{ + int i; + + /* DAC precision (normally 9-bit on real hardware, implemented through simple 14-bit channel output bitmasking) */ + bitmask = ~((1 << (TL_BITS - dac_bits)) - 1); + + /* update L/R panning bitmasks */ + for (i=0; i<2*6; i++) + { + if (ym2612.OPN.pan[i]) + { + ym2612.OPN.pan[i] = bitmask; + } + } +} + +int YM2612LoadContext(unsigned char *state) +{ + int c,s; + uint8 index; + int bufferptr = 0; + + /* restore YM2612 context */ + load_param(&ym2612, sizeof(ym2612)); + + /* restore DT table address pointer for each channel slots */ + for (c=0; c<6; c++) + { + for (s=0; s<4; s++) + { + load_param(&index,sizeof(index)); + bufferptr += sizeof(index); + ym2612.CH[c].SLOT[s].DT = ym2612.OPN.ST.dt_tab[index&7]; + } + } + + /* restore outputs connections */ + setup_connection(&ym2612.CH[0],0); + setup_connection(&ym2612.CH[1],1); + setup_connection(&ym2612.CH[2],2); + setup_connection(&ym2612.CH[3],3); + setup_connection(&ym2612.CH[4],4); + setup_connection(&ym2612.CH[5],5); + + return bufferptr; +} + +int YM2612SaveContext(unsigned char *state) +{ + int c,s; + uint8 index; + int bufferptr = 0; + + /* save YM2612 context */ + save_param(&ym2612, sizeof(ym2612)); + + /* save DT table index for each channel slots */ + for (c=0; c<6; c++) + { + for (s=0; s<4; s++) + { + index = (ym2612.CH[c].SLOT[s].DT - ym2612.OPN.ST.dt_tab[0]) >> 5; + save_param(&index,sizeof(index)); + bufferptr += sizeof(index); + } + } + + return bufferptr; +} diff --git a/genplus-gx/core/sound/ym2612.h b/genplus-gx/core/sound/ym2612.h new file mode 100644 index 0000000000..2cad8bfec5 --- /dev/null +++ b/genplus-gx/core/sound/ym2612.h @@ -0,0 +1,28 @@ +/* +** +** software implementation of Yamaha FM sound generator (YM2612/YM3438) +** +** Original code (MAME fm.c) +** +** Copyright (C) 2001, 2002, 2003 Jarek Burczynski (bujar at mame dot net) +** Copyright (C) 1998 Tatsuyuki Satoh , MultiArcadeMachineEmulator development +** +** Version 1.4 (final beta) +** +** Additional code & fixes by Eke-Eke for Genesis Plus GX +** +*/ + +#ifndef _H_YM2612_ +#define _H_YM2612_ + +extern void YM2612Init(void); +extern void YM2612Config(unsigned char dac_bits); +extern void YM2612ResetChip(void); +extern void YM2612Update(int *buffer, int length); +extern void YM2612Write(unsigned int a, unsigned int v); +extern unsigned int YM2612Read(void); +extern int YM2612LoadContext(unsigned char *state); +extern int YM2612SaveContext(unsigned char *state); + +#endif /* _YM2612_ */ diff --git a/genplus-gx/core/state.c b/genplus-gx/core/state.c new file mode 100644 index 0000000000..50b99c2187 --- /dev/null +++ b/genplus-gx/core/state.c @@ -0,0 +1,285 @@ +/*************************************************************************************** + * Genesis Plus + * Savestate support + * + * Copyright (C) 2007-2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +int state_load(unsigned char *state) +{ + int i, bufferptr = 0; + + /* signature check (GENPLUS-GX x.x.x) */ + char version[17]; + load_param(version,16); + version[16] = 0; + if (memcmp(version,STATE_VERSION,11)) + { + return 0; + } + + /* version check (keep compatibility with previous & current state version) */ + if ((version[11] < 0x31) || (version[13] < 0x37) || (version[15] < 0x31)) + { + return 0; + } + + /* reset system */ + system_reset(); + + /* enable VDP access for TMSS systems */ + for (i=0xc0; i<0xe0; i+=8) + { + m68k.memory_map[i].read8 = vdp_read_byte; + m68k.memory_map[i].read16 = vdp_read_word; + m68k.memory_map[i].write8 = vdp_write_byte; + m68k.memory_map[i].write16 = vdp_write_word; + zbank_memory_map[i].read = zbank_read_vdp; + zbank_memory_map[i].write = zbank_write_vdp; + } + + /* GENESIS */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + load_param(work_ram, sizeof(work_ram)); + load_param(zram, sizeof(zram)); + load_param(&zstate, sizeof(zstate)); + load_param(&zbank, sizeof(zbank)); + if (zstate == 3) + { + m68k.memory_map[0xa0].read8 = z80_read_byte; + m68k.memory_map[0xa0].read16 = z80_read_word; + m68k.memory_map[0xa0].write8 = z80_write_byte; + m68k.memory_map[0xa0].write16 = z80_write_word; + } + else + { + m68k.memory_map[0xa0].read8 = m68k_read_bus_8; + m68k.memory_map[0xa0].read16 = m68k_read_bus_16; + m68k.memory_map[0xa0].write8 = m68k_unused_8_w; + m68k.memory_map[0xa0].write16 = m68k_unused_16_w; + } + } + else + { + load_param(work_ram, 0x2000); + } + + /* IO */ + load_param(io_reg, sizeof(io_reg)); + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + io_reg[0] = region_code | 0x20 | (config.bios & 1); + } + else + { + io_reg[0] = 0x80 | (region_code >> 1); + } + + /* VDP */ + bufferptr += vdp_context_load(&state[bufferptr], version[15]); + + /* SOUND */ + bufferptr += sound_context_load(&state[bufferptr]); + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + SN76489_Init(snd.blips[0][0], snd.blips[0][1], SN_INTEGRATED); + SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff); + } + else + { + SN76489_Init(snd.blips[0][0], snd.blips[0][1], (system_hw < SYSTEM_MARKIII) ? SN_DISCRETE : SN_INTEGRATED); + SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, io_reg[6]); + } + + /* 68000 */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + uint16 tmp16; + uint32 tmp32; + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D0, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D1, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D2, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D3, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D4, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D5, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D6, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D7, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A0, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A1, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A2, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A3, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A4, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A5, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A6, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A7, tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_PC, tmp32); + load_param(&tmp16, 2); m68k_set_reg(M68K_REG_SR, tmp16); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_USP,tmp32); + load_param(&tmp32, 4); m68k_set_reg(M68K_REG_ISP,tmp32); + + load_param(&m68k.cycles, sizeof(m68k.cycles)); + load_param(&m68k.int_level, sizeof(m68k.int_level)); + load_param(&m68k.stopped, sizeof(m68k.stopped)); + } + + /* Z80 */ + load_param(&Z80, sizeof(Z80_Regs)); + Z80.irq_callback = z80_irq_callback; + + /* Extra HW */ + if (system_hw == SYSTEM_MCD) + { + /* handle case of MD cartridge using or not CD hardware */ + char id[5]; + load_param(id,4); + id[4] = 0; + + /* check if CD hardware was enabled before attempting to restore */ + if (memcmp(id,"SCD!",4)) + { + return 0; + } + + /* CD hardware */ + bufferptr += scd_context_load(&state[bufferptr]); + } + else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* MD cartridge hardware */ + bufferptr += md_cart_context_load(&state[bufferptr]); + } + else + { + /* MS cartridge hardware */ + bufferptr += sms_cart_context_load(&state[bufferptr]); + sms_cart_switch(~io_reg[0x0E]); + } + + return bufferptr; +} + +int state_save(unsigned char *state) +{ + /* buffer size */ + int bufferptr = 0; + + /* version string */ + char version[16]; + strncpy(version,STATE_VERSION,16); + save_param(version, 16); + + /* GENESIS */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + save_param(work_ram, sizeof(work_ram)); + save_param(zram, sizeof(zram)); + save_param(&zstate, sizeof(zstate)); + save_param(&zbank, sizeof(zbank)); + } + else + { + save_param(work_ram, 0x2000); + } + + /* IO */ + save_param(io_reg, sizeof(io_reg)); + + /* VDP */ + bufferptr += vdp_context_save(&state[bufferptr]); + + /* SOUND */ + bufferptr += sound_context_save(&state[bufferptr]); + + /* 68000 */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + uint16 tmp16; + uint32 tmp32; + tmp32 = m68k_get_reg(M68K_REG_D0); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_D1); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_D2); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_D3); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_D4); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_D5); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_D6); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_D7); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_A0); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_A1); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_A2); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_A3); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_A4); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_A5); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_A6); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_A7); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_PC); save_param(&tmp32, 4); + tmp16 = m68k_get_reg(M68K_REG_SR); save_param(&tmp16, 2); + tmp32 = m68k_get_reg(M68K_REG_USP); save_param(&tmp32, 4); + tmp32 = m68k_get_reg(M68K_REG_ISP); save_param(&tmp32, 4); + + save_param(&m68k.cycles, sizeof(m68k.cycles)); + save_param(&m68k.int_level, sizeof(m68k.int_level)); + save_param(&m68k.stopped, sizeof(m68k.stopped)); + } + + /* Z80 */ + save_param(&Z80, sizeof(Z80_Regs)); + + /* External HW */ + if (system_hw == SYSTEM_MCD) + { + /* CD hardware ID flag */ + char id[5]; + strncpy(id,"SCD!",4); + save_param(id, 4); + + /* CD hardware */ + bufferptr += scd_context_save(&state[bufferptr]); + } + else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* MD cartridge hardware */ + bufferptr += md_cart_context_save(&state[bufferptr]); + } + else + { + /* MS cartridge hardware */ + bufferptr += sms_cart_context_save(&state[bufferptr]); + } + + /* return total size */ + return bufferptr; +} diff --git a/genplus-gx/core/state.h b/genplus-gx/core/state.h new file mode 100644 index 0000000000..678d632858 --- /dev/null +++ b/genplus-gx/core/state.h @@ -0,0 +1,57 @@ +/*************************************************************************************** + * Genesis Plus + * Savestate support + * + * Copyright (C) 2007-2012 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _STATE_H_ +#define _STATE_H_ + +#define STATE_SIZE 0xfd000 +#define STATE_VERSION "GENPLUS-GX 1.7.5" + +#define load_param(param, size) \ + memcpy(param, &state[bufferptr], size); \ + bufferptr+= size; + +#define save_param(param, size) \ + memcpy(&state[bufferptr], param, size); \ + bufferptr+= size; + +/* Function prototypes */ +extern int state_load(unsigned char *state); +extern int state_save(unsigned char *state); + +#endif diff --git a/genplus-gx/core/system.c b/genplus-gx/core/system.c new file mode 100644 index 0000000000..d80a2557a9 --- /dev/null +++ b/genplus-gx/core/system.c @@ -0,0 +1,1384 @@ +/*************************************************************************************** + * Genesis Plus + * Virtual System emulation + * + * Support for "Genesis", "Genesis + CD" & "Master System" modes + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "eq.h" + +/* Global variables */ +t_bitmap bitmap; +t_snd snd; +uint32 mcycles_vdp; +uint8 system_hw; +uint8 system_bios; +uint32 system_clock; +int16 SVP_cycles = 800; + +static uint8 pause_b; +static EQSTATE eq; +static int16 llp,rrp; + +/******************************************************************************************/ +/* Audio subsystem */ +/******************************************************************************************/ + +int audio_init(int samplerate, double framerate) +{ + /* Number of M-cycles executed per second. */ + /* All emulated chips are kept in sync by using a common oscillator (MCLOCK) */ + /* */ + /* The original console would run exactly 53693175 M-cycles per sec (53203424 for PAL), */ + /* 3420 M-cycles per line and 262 (313 for PAL) lines per frame, which gives an exact */ + /* framerate of 59.92 (49.70 for PAL) frames per second. */ + /* */ + /* Since audio samples are generated at the end of the frame, to prevent audio skipping */ + /* or lag between emulated frames, number of samples rendered per frame must be set to */ + /* output samplerate (number of samples played per second) divided by input framerate */ + /* (number of frames emulated per seconds). */ + /* */ + /* On some systems, we may want to achieve 100% smooth video rendering by synchronizing */ + /* frame emulation with VSYNC, which frequency is generally not exactly those values. */ + /* In that case, input framerate (number of frames emulated per seconds) is the same as */ + /* output framerate (number of frames rendered per seconds) by the host video hardware. */ + /* */ + /* When no framerate is specified, base clock is set to original master clock value. */ + /* Otherwise, it is set to number of M-cycles emulated per line (fixed) multiplied by */ + /* number of lines per frame (VDP mode specific) multiplied by input framerate. */ + /* */ + double mclk = framerate ? (MCYCLES_PER_LINE * (vdp_pal ? 313 : 262) * framerate) : system_clock; + + /* Shutdown first */ + audio_shutdown(); + + /* Clear the sound data context */ + memset(&snd, 0, sizeof (snd)); + + /* Initialize audio rates */ + snd.sample_rate = samplerate; + snd.frame_rate = framerate; + + /* Initialize Blip Buffers */ + snd.blips[0][0] = blip_new(samplerate / 10); + snd.blips[0][1] = blip_new(samplerate / 10); + if (!snd.blips[0][0] || !snd.blips[0][1]) + { + audio_shutdown(); + return -1; + } + + /* For maximal accuracy, sound chips are running at their original rate using common */ + /* master clock timebase so they remain perfectly synchronized together, while still */ + /* being synchronized with 68K and Z80 CPUs as well. Mixed sound chip output is then */ + /* resampled to desired rate at the end of each frame, using Blip Buffer. */ + blip_set_rates(snd.blips[0][0], mclk, samplerate); + blip_set_rates(snd.blips[0][1], mclk, samplerate); + + /* Initialize PSG core */ + SN76489_Init(snd.blips[0][0], snd.blips[0][1], (system_hw < SYSTEM_MARKIII) ? SN_DISCRETE : SN_INTEGRATED); + + /* Mega CD sound hardware */ + if (system_hw == SYSTEM_MCD) + { + /* allocate blip buffers */ + snd.blips[1][0] = blip_new(samplerate / 10); + snd.blips[1][1] = blip_new(samplerate / 10); + snd.blips[2][0] = blip_new(samplerate / 10); + snd.blips[2][1] = blip_new(samplerate / 10); + if (!snd.blips[1][0] || !snd.blips[1][1] || !snd.blips[2][0] || !snd.blips[2][1]) + { + audio_shutdown(); + return -1; + } + + /* Initialize PCM core */ + pcm_init(snd.blips[1][0], snd.blips[1][1]); + + /* Initialize CDD core */ + cdd_init(snd.blips[2][0], snd.blips[2][1]); + } + + /* Set audio enable flag */ + snd.enabled = 1; + + /* Reset audio */ + audio_reset(); + + return (0); +} + +void audio_reset(void) +{ + int i,j; + + /* Clear blip buffers */ + for (i=0; i<3; i++) + { + for (j=0; j<2; j++) + { + if (snd.blips[i][j]) + { + blip_clear(snd.blips[i][j]); + } + } + } + + /* Low-Pass filter */ + llp = 0; + rrp = 0; + + /* 3 band EQ */ + audio_set_equalizer(); +} + +void audio_set_equalizer(void) +{ + init_3band_state(&eq,config.low_freq,config.high_freq,snd.sample_rate); + eq.lg = (double)(config.lg) / 100.0; + eq.mg = (double)(config.mg) / 100.0; + eq.hg = (double)(config.hg) / 100.0; +} + +void audio_shutdown(void) +{ + int i,j; + + /* Delete blip buffers */ + for (i=0; i<3; i++) + { + for (j=0; j<2; j++) + { + blip_delete(snd.blips[i][j]); + snd.blips[i][j] = 0; + } + } +} + +int audio_update(int16 *buffer) +{ + /* run sound chips until end of frame */ + int size = sound_update(mcycles_vdp); + + /* Mega CD specific */ + if (system_hw == SYSTEM_MCD) + { + /* sync PCM chip with other sound chips */ + pcm_update(size); + + /* read CDDA samples */ + cdd_read_audio(size); + } + +#ifdef ALIGN_SND + /* return an aligned number of samples if required */ + size &= ALIGN_SND; +#endif + + /* resample FM & PSG mixed stream to output buffer */ +#ifdef LSB_FIRST + blip_read_samples(snd.blips[0][0], buffer, size); + blip_read_samples(snd.blips[0][1], buffer + 1, size); +#else + blip_read_samples(snd.blips[0][0], buffer + 1, size); + blip_read_samples(snd.blips[0][1], buffer, size); +#endif + + /* Mega CD specific */ + if (system_hw == SYSTEM_MCD) + { + /* resample PCM & CD-DA streams to output buffer */ +#ifdef LSB_FIRST + blip_mix_samples(snd.blips[1][0], buffer, size); + blip_mix_samples(snd.blips[1][1], buffer + 1, size); + blip_mix_samples(snd.blips[2][0], buffer, size); + blip_mix_samples(snd.blips[2][1], buffer + 1, size); +#else + blip_mix_samples(snd.blips[1][0], buffer + 1, size); + blip_mix_samples(snd.blips[1][1], buffer, size); + blip_mix_samples(snd.blips[2][0], buffer + 1, size); + blip_mix_samples(snd.blips[2][1], buffer, size); +#endif + } + + /* Audio filtering */ + if (config.filter) + { + int samples = size; + int16 *out = buffer; + int32 l, r; + + if (config.filter & 1) + { + /* single-pole low-pass filter (6 dB/octave) */ + uint32 factora = config.lp_range; + uint32 factorb = 0x10000 - factora; + + /* restore previous sample */ + l = llp; + r = rrp; + + do + { + /* apply low-pass filter */ + l = l*factora + out[0]*factorb; + r = r*factora + out[1]*factorb; + + /* 16.16 fixed point */ + l >>= 16; + r >>= 16; + + /* update sound buffer */ + *out++ = l; + *out++ = r; + } + while (--samples); + + /* save last samples for next frame */ + llp = l; + rrp = r; + } + else if (config.filter & 2) + { + do + { + /* 3 Band EQ */ + l = do_3band(&eq,out[0]); + r = do_3band(&eq,out[1]); + + /* clipping (16-bit samples) */ + if (l > 32767) l = 32767; + else if (l < -32768) l = -32768; + if (r > 32767) r = 32767; + else if (r < -32768) r = -32768; + + /* update sound buffer */ + *out++ = l; + *out++ = r; + } + while (--samples); + } + } + + /* Mono output mixing */ + if (config.mono) + { + int16 out; + int samples = size; + do + { + out = (buffer[0] + buffer[1]) / 2; + *buffer++ = out; + *buffer++ = out; + } + while (--samples); + } + +#ifdef LOGSOUND + error("%d samples returned\n\n",size); +#endif + + return size; +} + +/**************************************************************** + * Virtual System emulation + ****************************************************************/ +void system_init(void) +{ + gen_init(); + io_init(); + vdp_init(); + render_init(); + sound_init(); +} + +void system_reset(void) +{ + gen_reset(1); + io_reset(); + render_reset(); + vdp_reset(); + sound_reset(); + audio_reset(); +} + +void system_frame_gen(int do_skip) +{ + /* line counters */ + int start, end, line = 0; + + /* Z80 interrupt flag */ + int zirq = 1; + + /* reload H Counter */ + int h_counter = reg[10]; + + /* reset frame cycle counter */ + mcycles_vdp = 0; + + /* reload V Counter */ + v_counter = lines_per_frame - 1; + + /* reset VDP FIFO */ + fifo_write_cnt = 0; + fifo_slots = 0; + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* display changed during VBLANK */ + if (bitmap.viewport.changed & 2) + { + /* interlaced modes */ + int old_interlaced = interlaced; + interlaced = (reg[12] & 0x02) >> 1; + + if (old_interlaced != interlaced) + { + /* double resolution mode */ + im2_flag = ((reg[12] & 0x06) == 0x06); + + /* reset field status flag */ + odd_frame = 1; + + /* video mode has changed */ + bitmap.viewport.changed = 5; + + /* update rendering mode */ + if (reg[1] & 0x04) + { + if (im2_flag) + { + render_bg = (reg[11] & 0x04) ? render_bg_m5_im2_vs : render_bg_m5_im2; + render_obj = (reg[12] & 0x08) ? render_obj_m5_im2_ste : render_obj_m5_im2; + } + else + { + render_bg = (reg[11] & 0x04) ? render_bg_m5_vs : render_bg_m5; + render_obj = (reg[12] & 0x08) ? render_obj_m5_ste : render_obj_m5; + } + } + } + else + { + /* clear flag */ + bitmap.viewport.changed &= ~2; + } + + /* active screen height */ + if (reg[1] & 0x04) + { + /* Mode 5 */ + if (reg[1] & 0x08) + { + /* 240 active lines */ + bitmap.viewport.h = 240; + bitmap.viewport.y = (config.overscan & 1) * 24 * vdp_pal; + } + else + { + /* 224 active lines */ + bitmap.viewport.h = 224; + bitmap.viewport.y = (config.overscan & 1) * (8 + (24 * vdp_pal)); + } + } + else + { + /* Mode 4 (192 active lines) */ + bitmap.viewport.h = 192; + bitmap.viewport.y = (config.overscan & 1) * 24 * (vdp_pal + 1); + } + + /* active screen width */ + bitmap.viewport.w = 256 + ((reg[12] & 0x01) << 6); + } + + /* clear VBLANK, DMA, FIFO FULL & field flags */ + status &= 0xFEE5; + + /* set FIFO EMPTY flag */ + status |= 0x0200; + + /* even/odd field flag (interlaced modes only) */ + odd_frame ^= 1; + if (interlaced) + { + status |= (odd_frame << 4); + } + + /* update VDP DMA */ + if (dma_length) + { + vdp_dma_update(0); + } + + /* render last line of overscan */ + if (bitmap.viewport.y > 0) + { + blank_line(v_counter, -bitmap.viewport.x, bitmap.viewport.w + 2*bitmap.viewport.x); + } + + /* parse first line of sprites */ + if (reg[1] & 0x40) + { + parse_satb(-1); + } + + /* run 68k & Z80 */ + m68k_run(MCYCLES_PER_LINE); + if (zstate == 1) + { + z80_run(MCYCLES_PER_LINE); + } + else + { + Z80.cycles = MCYCLES_PER_LINE; + } + + /* run SVP chip */ + if (svp) + { + ssp1601_run(SVP_cycles); + } + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + + /* Active Display */ + do + { + /* update V Counter */ + v_counter = line; + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* H Interrupt */ + if(--h_counter < 0) + { + /* reload H Counter */ + h_counter = reg[10]; + + /* interrupt level 4 */ + hint_pending = 0x10; + if (reg[0] & 0x10) + { + m68k_update_irq(4); + } + } + + /* update VDP DMA */ + if (dma_length) + { + vdp_dma_update(mcycles_vdp); + } + + /* render scanline */ + if (!do_skip) + { + render_line(line); + } + + /* run 68k & Z80 */ + m68k_run(mcycles_vdp + MCYCLES_PER_LINE); + if (zstate == 1) + { + z80_run(mcycles_vdp + MCYCLES_PER_LINE); + } + else + { + Z80.cycles = mcycles_vdp + MCYCLES_PER_LINE; + } + + /* run SVP chip */ + if (svp) + { + ssp1601_run(SVP_cycles); + } + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + } + while (++line < bitmap.viewport.h); + + /* end of active display */ + v_counter = line; + + /* set VBLANK flag */ + status |= 0x08; + + /* overscan area */ + start = lines_per_frame - bitmap.viewport.y; + end = bitmap.viewport.h + bitmap.viewport.y; + + /* check viewport changes */ + if ((bitmap.viewport.w != bitmap.viewport.ow) || (bitmap.viewport.h != bitmap.viewport.oh)) + { + bitmap.viewport.ow = bitmap.viewport.w; + bitmap.viewport.oh = bitmap.viewport.h; + bitmap.viewport.changed |= 1; + } + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* H Interrupt */ + if(--h_counter < 0) + { + /* reload H Counter */ + h_counter = reg[10]; + + /* interrupt level 4 */ + hint_pending = 0x10; + if (reg[0] & 0x10) + { + m68k_update_irq(4); + } + } + + /* update VDP DMA */ + if (dma_length) + { + vdp_dma_update(mcycles_vdp); + } + + /* render overscan */ + if (line < end) + { + blank_line(line, -bitmap.viewport.x, bitmap.viewport.w + 2*bitmap.viewport.x); + } + + /* update inputs before VINT (Warriors of Eternal Sun) */ + osd_input_update(); + + /* delay between VINT flag & V Interrupt (Ex-Mutants, Tyrant) */ + m68k_run(mcycles_vdp + 588); + status |= 0x80; + + /* delay between VBLANK flag & V Interrupt (Dracula, OutRunners, VR Troopers) */ + m68k_run(mcycles_vdp + 788); + if (zstate == 1) + { + z80_run(mcycles_vdp + 788); + } + else + { + Z80.cycles = mcycles_vdp + 788; + } + + /* V Interrupt */ + vint_pending = 0x20; + if (reg[1] & 0x20) + { + m68k_set_irq(6); + } + + /* assert Z80 interrupt */ + Z80.irq_state = ASSERT_LINE; + + /* run 68k & Z80 until end of line */ + m68k_run(mcycles_vdp + MCYCLES_PER_LINE); + if (zstate == 1) + { + z80_run(mcycles_vdp + MCYCLES_PER_LINE); + } + else + { + Z80.cycles = mcycles_vdp + MCYCLES_PER_LINE; + } + + /* run SVP chip */ + if (svp) + { + ssp1601_run(SVP_cycles); + } + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + + /* increment line count */ + line++; + + /* Vertical Blanking */ + do + { + /* update V Counter */ + v_counter = line; + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* render overscan */ + if ((line < end) || (line >= start)) + { + blank_line(line, -bitmap.viewport.x, bitmap.viewport.w + 2*bitmap.viewport.x); + } + + if (zirq) + { + /* Z80 interrupt is asserted exactly for one line */ + m68k_run(mcycles_vdp + 788); + if (zstate == 1) + { + z80_run(mcycles_vdp + 788); + } + else + { + Z80.cycles = mcycles_vdp + 788; + } + + /* clear Z80 interrupt */ + Z80.irq_state = CLEAR_LINE; + zirq = 0; + } + + /* run 68k & Z80 */ + m68k_run(mcycles_vdp + MCYCLES_PER_LINE); + if (zstate == 1) + { + z80_run(mcycles_vdp + MCYCLES_PER_LINE); + } + else + { + Z80.cycles = mcycles_vdp + MCYCLES_PER_LINE; + } + + /* run SVP chip */ + if (svp) + { + ssp1601_run(SVP_cycles); + } + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + } + while (++line < (lines_per_frame - 1)); + + /* adjust CPU cycle counters for next frame */ + m68k.cycles -= mcycles_vdp; + Z80.cycles -= mcycles_vdp; +} + +void system_frame_scd(int do_skip) +{ + /* line counters */ + int start, end, line = 0; + + /* Z80 interrupt flag */ + int zirq = 1; + + /* reload H Counter */ + int h_counter = reg[10]; + + /* reset frame cycle counters */ + mcycles_vdp = 0; + scd.cycles = 0; + + /* reload V Counter */ + v_counter = lines_per_frame - 1; + + /* reset VDP FIFO */ + fifo_write_cnt = 0; + fifo_slots = 0; + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* display changed during VBLANK */ + if (bitmap.viewport.changed & 2) + { + /* interlaced modes */ + int old_interlaced = interlaced; + interlaced = (reg[12] & 0x02) >> 1; + + if (old_interlaced != interlaced) + { + /* double resolution mode */ + im2_flag = ((reg[12] & 0x06) == 0x06); + + /* reset field status flag */ + odd_frame = 1; + + /* video mode has changed */ + bitmap.viewport.changed = 5; + + /* update rendering mode */ + if (reg[1] & 0x04) + { + if (im2_flag) + { + render_bg = (reg[11] & 0x04) ? render_bg_m5_im2_vs : render_bg_m5_im2; + render_obj = (reg[12] & 0x08) ? render_obj_m5_im2_ste : render_obj_m5_im2; + } + else + { + render_bg = (reg[11] & 0x04) ? render_bg_m5_vs : render_bg_m5; + render_obj = (reg[12] & 0x08) ? render_obj_m5_ste : render_obj_m5; + } + } + } + else + { + /* clear flag */ + bitmap.viewport.changed &= ~2; + } + + /* active screen height */ + if (reg[1] & 0x04) + { + bitmap.viewport.h = 224 + ((reg[1] & 0x08) << 1); + bitmap.viewport.y = (config.overscan & 1) * ((240 + 48*vdp_pal - bitmap.viewport.h) >> 1); + } + else + { + bitmap.viewport.h = 192; + bitmap.viewport.y = (config.overscan & 1) * 24 * (vdp_pal + 1); + } + + /* active screen width */ + bitmap.viewport.w = 256 + ((reg[12] & 0x01) << 6); + } + + /* clear VBLANK, DMA, FIFO FULL & field flags */ + status &= 0xFEE5; + + /* set FIFO EMPTY flag */ + status |= 0x0200; + + /* even/odd field flag (interlaced modes only) */ + odd_frame ^= 1; + if (interlaced) + { + status |= (odd_frame << 4); + } + + /* update VDP DMA */ + if (dma_length) + { + vdp_dma_update(0); + } + + /* render last line of overscan */ + if (bitmap.viewport.y > 0) + { + blank_line(v_counter, -bitmap.viewport.x, bitmap.viewport.w + 2*bitmap.viewport.x); + } + + /* parse first line of sprites */ + if (reg[1] & 0x40) + { + parse_satb(-1); + } + + /* run both 68k & CD hardware */ + scd_update(MCYCLES_PER_LINE); + + /* run Z80 */ + if (zstate == 1) + { + z80_run(MCYCLES_PER_LINE); + } + else + { + Z80.cycles = MCYCLES_PER_LINE; + } + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + + /* Active Display */ + do + { + /* update V Counter */ + v_counter = line; + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* H Interrupt */ + if(--h_counter < 0) + { + /* reload H Counter */ + h_counter = reg[10]; + + /* interrupt level 4 */ + hint_pending = 0x10; + if (reg[0] & 0x10) + { + m68k_update_irq(4); + } + } + + /* update VDP DMA */ + if (dma_length) + { + vdp_dma_update(mcycles_vdp); + } + + /* render scanline */ + if (!do_skip) + { + render_line(line); + } + + /* run both 68k & CD hardware */ + scd_update(mcycles_vdp + MCYCLES_PER_LINE); + + /* run Z80 */ + if (zstate == 1) + { + z80_run(mcycles_vdp + MCYCLES_PER_LINE); + } + else + { + Z80.cycles = mcycles_vdp + MCYCLES_PER_LINE; + } + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + } + while (++line < bitmap.viewport.h); + + /* end of active display */ + v_counter = line; + + /* set VBLANK flag */ + status |= 0x08; + + /* overscan area */ + start = lines_per_frame - bitmap.viewport.y; + end = bitmap.viewport.h + bitmap.viewport.y; + + /* check viewport changes */ + if ((bitmap.viewport.w != bitmap.viewport.ow) || (bitmap.viewport.h != bitmap.viewport.oh)) + { + bitmap.viewport.ow = bitmap.viewport.w; + bitmap.viewport.oh = bitmap.viewport.h; + bitmap.viewport.changed |= 1; + } + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* H Interrupt */ + if(--h_counter < 0) + { + /* reload H Counter */ + h_counter = reg[10]; + + /* interrupt level 4 */ + hint_pending = 0x10; + if (reg[0] & 0x10) + { + m68k_update_irq(4); + } + } + + /* update VDP DMA */ + if (dma_length) + { + vdp_dma_update(mcycles_vdp); + } + + /* render overscan */ + if (line < end) + { + blank_line(line, -bitmap.viewport.x, bitmap.viewport.w + 2*bitmap.viewport.x); + } + + /* update inputs before VINT (Warriors of Eternal Sun) */ + osd_input_update(); + + /* delay between VINT flag & V Interrupt (Ex-Mutants, Tyrant) */ + m68k_run(mcycles_vdp + 588); + status |= 0x80; + + /* delay between VBLANK flag & V Interrupt (Dracula, OutRunners, VR Troopers) */ + m68k_run(mcycles_vdp + 788); + if (zstate == 1) + { + z80_run(mcycles_vdp + 788); + } + else + { + Z80.cycles = mcycles_vdp + 788; + } + + /* V Interrupt */ + vint_pending = 0x20; + if (reg[1] & 0x20) + { + m68k_set_irq(6); + } + + /* assert Z80 interrupt */ + Z80.irq_state = ASSERT_LINE; + + /* run both 68k & CD hardware */ + scd_update(mcycles_vdp + MCYCLES_PER_LINE); + + /* run Z80 until end of line */ + if (zstate == 1) + { + z80_run(mcycles_vdp + MCYCLES_PER_LINE); + } + else + { + Z80.cycles = mcycles_vdp + MCYCLES_PER_LINE; + } + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + + /* increment line count */ + line++; + + /* Vertical Blanking */ + do + { + /* update V Counter */ + v_counter = line; + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* render overscan */ + if ((line < end) || (line >= start)) + { + blank_line(line, -bitmap.viewport.x, bitmap.viewport.w + 2*bitmap.viewport.x); + } + + if (zirq) + { + /* Z80 interrupt is asserted exactly for one line */ + m68k_run(mcycles_vdp + 788); + if (zstate == 1) + { + z80_run(mcycles_vdp + 788); + } + else + { + Z80.cycles = mcycles_vdp + 788; + } + + /* clear Z80 interrupt */ + Z80.irq_state = CLEAR_LINE; + zirq = 0; + } + + /* run both 68k & CD hardware */ + scd_update(mcycles_vdp + MCYCLES_PER_LINE); + + /* run Z80 */ + if (zstate == 1) + { + z80_run(mcycles_vdp + MCYCLES_PER_LINE); + } + else + { + Z80.cycles = mcycles_vdp + MCYCLES_PER_LINE; + } + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + } + while (++line < (lines_per_frame - 1)); + + /* prepare for next SCD frame */ + scd_end_frame(scd.cycles); + + /* adjust CPU cycle counters for next frame */ + Z80.cycles -= mcycles_vdp; + m68k.cycles -= mcycles_vdp; +} + +void system_frame_sms(int do_skip) +{ + /* line counter */ + int start, end, line = 0; + + /* reload H Counter */ + int h_counter = reg[10]; + + /* reset line master cycle count */ + mcycles_vdp = 0; + + /* reload V Counter */ + v_counter = lines_per_frame - 1; + + /* reset VDP FIFO */ + fifo_write_cnt = 0; + fifo_slots = 0; + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* display changed during VBLANK */ + if (bitmap.viewport.changed & 2) + { + bitmap.viewport.changed &= ~2; + + if (system_hw & SYSTEM_MD) + { + /* interlaced mode */ + int old_interlaced = interlaced; + interlaced = (reg[12] & 0x02) >> 1; + if (old_interlaced != interlaced) + { + im2_flag = ((reg[12] & 0x06) == 0x06); + odd_frame = 1; + bitmap.viewport.changed = 5; + + /* update rendering mode */ + if (reg[1] & 0x04) + { + if (im2_flag) + { + render_bg = (reg[11] & 0x04) ? render_bg_m5_im2_vs : render_bg_m5_im2; + render_obj = render_obj_m5_im2; + + } + else + { + render_bg = (reg[11] & 0x04) ? render_bg_m5_vs : render_bg_m5; + render_obj = render_obj_m5; + } + } + } + + /* active screen height */ + if (reg[1] & 0x04) + { + bitmap.viewport.h = 224 + ((reg[1] & 0x08) << 1); + bitmap.viewport.y = (config.overscan & 1) * ((240 + 48*vdp_pal - bitmap.viewport.h) >> 1); + } + else + { + bitmap.viewport.h = 192; + bitmap.viewport.y = (config.overscan & 1) * 24 * (vdp_pal + 1); + } + + /* active screen width */ + bitmap.viewport.w = 256 + ((reg[12] & 0x01) << 6); + } + else + { + /* check for VDP extended modes */ + int mode = (reg[0] & 0x06) | (reg[1] & 0x18); + + /* update active height */ + if (mode == 0x0E) + { + bitmap.viewport.h = 240; + } + else if (mode == 0x16) + { + bitmap.viewport.h = 224; + } + else + { + bitmap.viewport.h = 192; + } + + /* update vertical overscan */ + if (config.overscan & 1) + { + bitmap.viewport.y = (240 + 48*vdp_pal - bitmap.viewport.h) >> 1; + } + else + { + if ((system_hw == SYSTEM_GG) && !config.gg_extra) + { + /* Display area reduced to 160x144 */ + bitmap.viewport.y = (144 - bitmap.viewport.h) / 2; + } + else + { + bitmap.viewport.y = 0; + } + } + } + } + + /* Detect pause button input (in Game Gear Mode, NMI is not generated) */ + if (system_hw != SYSTEM_GG) + { + if (input.pad[0] & INPUT_START) + { + /* NMI is edge-triggered */ + if (!pause_b) + { + pause_b = 1; + z80_set_nmi_line(ASSERT_LINE); + z80_set_nmi_line(CLEAR_LINE); + } + } + else + { + pause_b = 0; + } + } + + /* 3-D glasses faking: skip rendering of left lens frame */ + do_skip |= (work_ram[0x1ffb] & cart.special & HW_3D_GLASSES); + + /* Mega Drive VDP specific */ + if (system_hw & SYSTEM_MD) + { + /* clear VBLANK, DMA & field flags */ + status &= 0xE5; + + /* even/odd field flag (interlaced modes only) */ + odd_frame ^= 1; + if (interlaced) + { + status |= (odd_frame << 4); + } + + /* update VDP DMA */ + if (dma_length) + { + vdp_dma_update(0); + } + } + + /* Master System & Game Gear VDP specific */ + if (system_hw < SYSTEM_MD) + { + /* Sprites are still processed during vertical borders */ + if (reg[1] & 0x40) + { + render_obj(1); + } + } + + /* render last line of overscan */ + if (bitmap.viewport.y > 0) + { + blank_line(v_counter, -bitmap.viewport.x, bitmap.viewport.w + 2*bitmap.viewport.x); + } + + /* parse first line of sprites (on Master System VDP, pre-processing still occurs when display is disabled) */ + if ((reg[1] & 0x40) || (system_hw < SYSTEM_MD)) + { + parse_satb(-1); + } + + /* run Z80 */ + z80_run(MCYCLES_PER_LINE); + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + + /* latch Vertical Scroll register */ + vscroll = reg[0x09]; + + /* Active Display */ + do + { + /* update VDP DMA (Mega Drive VDP specific) */ + if (dma_length) + { + vdp_dma_update(mcycles_vdp); + } + + /* make sure we didn't already render that line */ + if (v_counter != line) + { + /* update V Counter */ + v_counter = line; + + /* render scanline */ + if (!do_skip) + { + render_line(line); + } + } + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* H Interrupt */ + if(--h_counter < 0) + { + /* reload H Counter */ + h_counter = reg[10]; + + /* interrupt level 4 */ + hint_pending = 0x10; + if (reg[0] & 0x10) + { + /* cycle-accurate HINT */ + /* IRQ line is latched between instructions, during instruction last cycle. */ + /* This means that if Z80 cycle count is exactly a multiple of MCYCLES_PER_LINE, */ + /* interrupt should be triggered AFTER the next instruction. */ + if ((Z80.cycles % MCYCLES_PER_LINE) == 0) + { + z80_run(Z80.cycles + 1); + } + + Z80.irq_state = ASSERT_LINE; + } + } + + /* run Z80 */ + z80_run(mcycles_vdp + MCYCLES_PER_LINE); + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + } + while (++line < bitmap.viewport.h); + + /* end of active display */ + v_counter = line; + + /* Mega Drive VDP specific */ + if (system_hw & SYSTEM_MD) + { + /* set VBLANK flag */ + status |= 0x08; + } + + /* overscan area */ + start = lines_per_frame - bitmap.viewport.y; + end = bitmap.viewport.h + bitmap.viewport.y; + + /* check viewport changes */ + if ((bitmap.viewport.w != bitmap.viewport.ow) || (bitmap.viewport.h != bitmap.viewport.oh)) + { + bitmap.viewport.ow = bitmap.viewport.w; + bitmap.viewport.oh = bitmap.viewport.h; + bitmap.viewport.changed |= 1; + } + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* H Interrupt */ + if(--h_counter < 0) + { + /* reload H Counter */ + h_counter = reg[10]; + + /* interrupt level 4 */ + hint_pending = 0x10; + if (reg[0] & 0x10) + { + /* cycle-accurate HINT */ + if ((Z80.cycles % MCYCLES_PER_LINE) == 0) + { + z80_run(Z80.cycles + 1); + } + + Z80.irq_state = ASSERT_LINE; + } + } + + /* update VDP DMA (Mega Drive VDP specific) */ + if (dma_length) + { + vdp_dma_update(mcycles_vdp); + } + + /* render overscan */ + if (line < end) + { + blank_line(line, -bitmap.viewport.x, bitmap.viewport.w + 2*bitmap.viewport.x); + } + + /* update inputs before VINT */ + osd_input_update(); + + /* run Z80 until end of line */ + z80_run(mcycles_vdp + MCYCLES_PER_LINE); + + /* make sure VINT flag was not cleared by last instruction */ + if (v_counter == line) + { + /* Set VINT flag */ + status |= 0x80; + + /* V Interrupt */ + vint_pending = 0x20; + if (reg[1] & 0x20) + { + Z80.irq_state = ASSERT_LINE; + } + } + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + + /* increment line count */ + line++; + + /* Vertical Blanking */ + do + { + /* update V Counter */ + v_counter = line; + + /* update 6-Buttons & Lightguns */ + input_refresh(); + + /* Master System & Game Gear VDP specific */ + if ((system_hw < SYSTEM_MD) && (line > (lines_per_frame - 16))) + { + /* Sprites are still processed during top border */ + render_obj((line - lines_per_frame) & 1); + parse_satb(line - lines_per_frame); + } + + /* render overscan */ + if ((line < end) || (line >= start)) + { + blank_line(line, -bitmap.viewport.x, bitmap.viewport.w + 2*bitmap.viewport.x); + } + + /* run Z80 */ + z80_run(mcycles_vdp + MCYCLES_PER_LINE); + + /* update line cycle count */ + mcycles_vdp += MCYCLES_PER_LINE; + } + while (++line < (lines_per_frame - 1)); + + /* adjust Z80 cycle count for next frame */ + Z80.cycles -= mcycles_vdp; +} diff --git a/genplus-gx/core/system.h b/genplus-gx/core/system.h new file mode 100644 index 0000000000..b679421f97 --- /dev/null +++ b/genplus-gx/core/system.h @@ -0,0 +1,119 @@ +/*************************************************************************************** + * Genesis Plus + * Virtual System emulation + * + * Support for "Genesis", "Genesis + CD" & "Master System" modes + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _SYSTEM_H_ +#define _SYSTEM_H_ + +#include "blip_buf.h" + +/* Supported hardware models */ +#define SYSTEM_SG 0x10 +#define SYSTEM_MARKIII 0x11 +#define SYSTEM_SMS 0x20 +#define SYSTEM_SMS2 0x21 +#define SYSTEM_GG 0x40 +#define SYSTEM_GGMS 0x41 +#define SYSTEM_MD 0x80 +#define SYSTEM_PBC 0x81 +#define SYSTEM_PICO 0x82 +#define SYSTEM_MCD 0x84 + +/* NTSC & PAL Master Clock frequencies */ +#define MCLOCK_NTSC 53693175 +#define MCLOCK_PAL 53203424 + +/* Number of M-Cycles executed per line */ +#define MCYCLES_PER_LINE 3420 + +/* Horizontal timing offsets when running in Z80 mode */ +#define SMS_CYCLE_OFFSET 530 +#define PBC_CYCLE_OFFSET 560 + +typedef struct +{ + uint8 *data; /* Bitmap data */ + int width; /* Bitmap width */ + int height; /* Bitmap height */ + int pitch; /* Bitmap pitch */ + struct + { + int x; /* X offset of viewport within bitmap */ + int y; /* Y offset of viewport within bitmap */ + int w; /* Width of viewport */ + int h; /* Height of viewport */ + int ow; /* Previous width of viewport */ + int oh; /* Previous height of viewport */ + int changed; /* 1= Viewport width or height have changed */ + } viewport; +} t_bitmap; + +typedef struct +{ + int sample_rate; /* Output Sample rate (8000-48000) */ + double frame_rate; /* Output Frame rate (usually 50 or 60 frames per second) */ + int enabled; /* 1= sound emulation is enabled */ + blip_t* blips[3][2]; /* Blip Buffer resampling */ +} t_snd; + + +/* Global variables */ +extern t_bitmap bitmap; +extern t_snd snd; +extern uint32 mcycles_vdp; +extern int16 SVP_cycles; +extern uint8 system_hw; +extern uint8 system_bios; +extern uint32 system_clock; + +/* Function prototypes */ +extern int audio_init(int samplerate, double framerate); +extern void audio_reset(void); +extern void audio_shutdown(void); +extern int audio_update(int16 *buffer); +extern void audio_set_equalizer(void); +extern void system_init(void); +extern void system_reset(void); +extern void system_frame_gen(int do_skip); +extern void system_frame_scd(int do_skip); +extern void system_frame_sms(int do_skip); + +#endif /* _SYSTEM_H_ */ + diff --git a/genplus-gx/core/tremor/CHANGELOG b/genplus-gx/core/tremor/CHANGELOG new file mode 100644 index 0000000000..53f23351e2 --- /dev/null +++ b/genplus-gx/core/tremor/CHANGELOG @@ -0,0 +1,19 @@ +*** 20020517: 1.0.2 *** + + Playback bugfix to floor1; mode mistakenly used for sizing instead + of blockflag + +*** 20020515: 1.0.1 *** + + Added complete API documentation to source tarball. No code + changes. + +*** 20020412: 1.0.1 *** + + Fixed a clipping bug that affected ARM processors; negative + overflows were being properly clipped, but then clobbered to + positive by the positive overflow chec (asm_arm.h:CLIP_TO_15) + +*** 20020403: 1.0.0 *** + + Initial version \ No newline at end of file diff --git a/genplus-gx/core/tremor/COPYING b/genplus-gx/core/tremor/COPYING new file mode 100644 index 0000000000..6111c6c5a6 --- /dev/null +++ b/genplus-gx/core/tremor/COPYING @@ -0,0 +1,28 @@ +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/genplus-gx/core/tremor/README b/genplus-gx/core/tremor/README new file mode 100644 index 0000000000..1321175322 --- /dev/null +++ b/genplus-gx/core/tremor/README @@ -0,0 +1,46 @@ +This README covers the Ogg Vorbis 'Tremor' integer playback codec +source as of date 2002 09 02, version 1.0.0. + + ****** + +The C source in this package will build on any ANSI C compiler and +function completely and properly on any platform. The included build +system assumes GNU build system and make tools (m4, automake, +autoconf, libtool and gmake). GCC is not required, although GCC is +the most tested compiler. To build using GNU tools, type in the +source directory: + +./autogen.sh +make + +Currently, the source implements playback in pure C on all platforms +except ARM, where a [currently] small amount of assembly (see +asm_arm.h) is used to implement 64 bit math operations and fast LSP +computation. If building on ARM without the benefit of GNU build +system tools, be sure that '_ARM_ASSEM_' is #defined by the build +system if this assembly is desired, else the resulting library will +use whatever 64 bit math builtins the compiler implements. + +No math library is required by this source. No floating point +operations are used at any point in either setup or decode. This +decoder library will properly decode any past, current or future +Vorbis I file or stream. + + ******** + +The build system produces a static and [when supported by the OS] +dynamic library named 'libvorbisidec'. This library exposes an API +nearly identical to the BSD reference library's 'libvorbisfile', +including all the features familiar to users of vorbisfile. This API +is similar enough that the proper header file to include is named +'ivorbisfile.h' [included in the source build directory]. Lower level +libvorbis-style headers and structures are in 'ivorbiscodec.h' +[included in the source build directory]. A simple example program, +ivorbisfile_example.c, can be built with 'make example'. + + ******** + +Detailed Tremor API Documentation begins at doc/index.html + +Monty +xiph.org diff --git a/genplus-gx/core/tremor/Version_script.in b/genplus-gx/core/tremor/Version_script.in new file mode 100644 index 0000000000..2eb1d87460 --- /dev/null +++ b/genplus-gx/core/tremor/Version_script.in @@ -0,0 +1,49 @@ +# +# Export file for libvorbisidec +# +# Only the symbols listed in the global section will be callable from +# applications linking to libvorbisidec. +# + +@PACKAGE@.so.1 +{ + global: + ov_clear; + ov_open; + ov_open_callbacks; + ov_test; + ov_test_callbacks; + ov_test_open; + ov_bitrate; + ov_bitrate_instant; + ov_streams; + ov_seekable; + ov_serialnumber; + ov_raw_total; + ov_pcm_total; + ov_time_total; + ov_raw_seek; + ov_pcm_seek; + ov_pcm_seek_page; + ov_time_seek; + ov_time_seek_page; + ov_raw_tell; + ov_pcm_tell; + ov_time_tell; + ov_info; + ov_comment; + ov_read; + + vorbis_info_init; + vorbis_info_clear; + vorbis_info_blocksize; + vorbis_comment_init; + vorbis_comment_add; + vorbis_comment_add_tag; + vorbis_comment_query; + vorbis_comment_query_count; + vorbis_comment_clear; + + local: + *; +}; diff --git a/genplus-gx/core/tremor/asm_arm.h b/genplus-gx/core/tremor/asm_arm.h new file mode 100644 index 0000000000..3a3716df1f --- /dev/null +++ b/genplus-gx/core/tremor/asm_arm.h @@ -0,0 +1,243 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: arm7 and later wide math functions + + ********************************************************************/ + +#ifdef _ARM_ASSEM_ + +#if !defined(_V_WIDE_MATH) && !defined(_LOW_ACCURACY_) +#define _V_WIDE_MATH + +static inline ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { + int lo,hi; + asm volatile("smull\t%0, %1, %2, %3" + : "=&r"(lo),"=&r"(hi) + : "%r"(x),"r"(y) + : "cc"); + return(hi); +} + +static inline ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { + return MULT32(x,y)<<1; +} + +static inline ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) { + int lo,hi; + asm volatile("smull %0, %1, %2, %3\n\t" + "movs %0, %0, lsr #15\n\t" + "adc %1, %0, %1, lsl #17\n\t" + : "=&r"(lo),"=&r"(hi) + : "%r"(x),"r"(y) + : "cc"); + return(hi); +} + +#define MB() asm volatile ("" : : : "memory") + +static inline void XPROD32(ogg_int32_t a, ogg_int32_t b, + ogg_int32_t t, ogg_int32_t v, + ogg_int32_t *x, ogg_int32_t *y) +{ + int x1, y1, l; + asm( "smull %0, %1, %4, %6\n\t" + "smlal %0, %1, %5, %7\n\t" + "rsb %3, %4, #0\n\t" + "smull %0, %2, %5, %6\n\t" + "smlal %0, %2, %3, %7" + : "=&r" (l), "=&r" (x1), "=&r" (y1), "=r" (a) + : "3" (a), "r" (b), "r" (t), "r" (v) + : "cc" ); + *x = x1; + MB(); + *y = y1; +} + +static inline void XPROD31(ogg_int32_t a, ogg_int32_t b, + ogg_int32_t t, ogg_int32_t v, + ogg_int32_t *x, ogg_int32_t *y) +{ + int x1, y1, l; + asm( "smull %0, %1, %4, %6\n\t" + "smlal %0, %1, %5, %7\n\t" + "rsb %3, %4, #0\n\t" + "smull %0, %2, %5, %6\n\t" + "smlal %0, %2, %3, %7" + : "=&r" (l), "=&r" (x1), "=&r" (y1), "=r" (a) + : "3" (a), "r" (b), "r" (t), "r" (v) + : "cc" ); + *x = x1 << 1; + MB(); + *y = y1 << 1; +} + +static inline void XNPROD31(ogg_int32_t a, ogg_int32_t b, + ogg_int32_t t, ogg_int32_t v, + ogg_int32_t *x, ogg_int32_t *y) +{ + int x1, y1, l; + asm( "rsb %2, %4, #0\n\t" + "smull %0, %1, %3, %5\n\t" + "smlal %0, %1, %2, %6\n\t" + "smull %0, %2, %4, %5\n\t" + "smlal %0, %2, %3, %6" + : "=&r" (l), "=&r" (x1), "=&r" (y1) + : "r" (a), "r" (b), "r" (t), "r" (v) + : "cc" ); + *x = x1 << 1; + MB(); + *y = y1 << 1; +} + +#endif + +#ifndef _V_CLIP_MATH +#define _V_CLIP_MATH + +static inline ogg_int32_t CLIP_TO_15(ogg_int32_t x) { + int tmp; + asm volatile("subs %1, %0, #32768\n\t" + "movpl %0, #0x7f00\n\t" + "orrpl %0, %0, #0xff\n" + "adds %1, %0, #32768\n\t" + "movmi %0, #0x8000" + : "+r"(x),"=r"(tmp) + : + : "cc"); + return(x); +} + +#endif + +#ifndef _V_LSP_MATH_ASM +#define _V_LSP_MATH_ASM + +static inline void lsp_loop_asm(ogg_uint32_t *qip,ogg_uint32_t *pip, + ogg_int32_t *qexpp, + ogg_int32_t *ilsp,ogg_int32_t wi, + ogg_int32_t m){ + + ogg_uint32_t qi=*qip,pi=*pip; + ogg_int32_t qexp=*qexpp; + + asm("mov r0,%3;" + "mov r1,%5,asr#1;" + "add r0,r0,r1,lsl#3;" + "1:" + + "ldmdb r0!,{r1,r3};" + "subs r1,r1,%4;" //ilsp[j]-wi + "rsbmi r1,r1,#0;" //labs(ilsp[j]-wi) + "umull %0,r2,r1,%0;" //qi*=labs(ilsp[j]-wi) + + "subs r1,r3,%4;" //ilsp[j+1]-wi + "rsbmi r1,r1,#0;" //labs(ilsp[j+1]-wi) + "umull %1,r3,r1,%1;" //pi*=labs(ilsp[j+1]-wi) + + "cmn r2,r3;" // shift down 16? + "beq 0f;" + "add %2,%2,#16;" + "mov %0,%0,lsr #16;" + "orr %0,%0,r2,lsl #16;" + "mov %1,%1,lsr #16;" + "orr %1,%1,r3,lsl #16;" + "0:" + "cmp r0,%3;\n" + "bhi 1b;\n" + + // odd filter assymetry + "ands r0,%5,#1;\n" + "beq 2f;\n" + "add r0,%3,%5,lsl#2;\n" + + "ldr r1,[r0,#-4];\n" + "mov r0,#0x4000;\n" + + "subs r1,r1,%4;\n" //ilsp[j]-wi + "rsbmi r1,r1,#0;\n" //labs(ilsp[j]-wi) + "umull %0,r2,r1,%0;\n" //qi*=labs(ilsp[j]-wi) + "umull %1,r3,r0,%1;\n" //pi*=labs(ilsp[j+1]-wi) + + "cmn r2,r3;\n" // shift down 16? + "beq 2f;\n" + "add %2,%2,#16;\n" + "mov %0,%0,lsr #16;\n" + "orr %0,%0,r2,lsl #16;\n" + "mov %1,%1,lsr #16;\n" + "orr %1,%1,r3,lsl #16;\n" + + //qi=(pi>>shift)*labs(ilsp[j]-wi); + //pi=(qi>>shift)*labs(ilsp[j+1]-wi); + //qexp+=shift; + + //} + + /* normalize to max 16 sig figs */ + "2:" + "mov r2,#0;" + "orr r1,%0,%1;" + "tst r1,#0xff000000;" + "addne r2,r2,#8;" + "movne r1,r1,lsr #8;" + "tst r1,#0x00f00000;" + "addne r2,r2,#4;" + "movne r1,r1,lsr #4;" + "tst r1,#0x000c0000;" + "addne r2,r2,#2;" + "movne r1,r1,lsr #2;" + "tst r1,#0x00020000;" + "addne r2,r2,#1;" + "movne r1,r1,lsr #1;" + "tst r1,#0x00010000;" + "addne r2,r2,#1;" + "mov %0,%0,lsr r2;" + "mov %1,%1,lsr r2;" + "add %2,%2,r2;" + + : "+r"(qi),"+r"(pi),"+r"(qexp) + : "r"(ilsp),"r"(wi),"r"(m) + : "r0","r1","r2","r3","cc"); + + *qip=qi; + *pip=pi; + *qexpp=qexp; +} + +static inline void lsp_norm_asm(ogg_uint32_t *qip,ogg_int32_t *qexpp){ + + ogg_uint32_t qi=*qip; + ogg_int32_t qexp=*qexpp; + + asm("tst %0,#0x0000ff00;" + "moveq %0,%0,lsl #8;" + "subeq %1,%1,#8;" + "tst %0,#0x0000f000;" + "moveq %0,%0,lsl #4;" + "subeq %1,%1,#4;" + "tst %0,#0x0000c000;" + "moveq %0,%0,lsl #2;" + "subeq %1,%1,#2;" + "tst %0,#0x00008000;" + "moveq %0,%0,lsl #1;" + "subeq %1,%1,#1;" + : "+r"(qi),"+r"(qexp) + : + : "cc"); + *qip=qi; + *qexpp=qexp; +} + +#endif +#endif + diff --git a/genplus-gx/core/tremor/backends.h b/genplus-gx/core/tremor/backends.h new file mode 100644 index 0000000000..50c1c45cfd --- /dev/null +++ b/genplus-gx/core/tremor/backends.h @@ -0,0 +1,130 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: backend and mapping structures + + ********************************************************************/ + +/* this is exposed up here because we need it for static modes. + Lookups for each backend aren't exposed because there's no reason + to do so */ + +#ifndef _vorbis_backend_h_ +#define _vorbis_backend_h_ + +#include "codec_internal.h" + +/* this would all be simpler/shorter with templates, but.... */ +/* Transform backend generic *************************************/ + +/* only mdct right now. Flesh it out more if we ever transcend mdct + in the transform domain */ + +/* Floor backend generic *****************************************/ +typedef struct{ + vorbis_info_floor *(*unpack)(vorbis_info *,oggpack_buffer *); + vorbis_look_floor *(*look) (vorbis_dsp_state *,vorbis_info_mode *, + vorbis_info_floor *); + void (*free_info) (vorbis_info_floor *); + void (*free_look) (vorbis_look_floor *); + void *(*inverse1) (struct vorbis_block *,vorbis_look_floor *); + int (*inverse2) (struct vorbis_block *,vorbis_look_floor *, + void *buffer,ogg_int32_t *); +} vorbis_func_floor; + +typedef struct{ + int order; + long rate; + long barkmap; + + int ampbits; + int ampdB; + + int numbooks; /* <= 16 */ + int books[16]; + +} vorbis_info_floor0; + +#define VIF_POSIT 63 +#define VIF_CLASS 16 +#define VIF_PARTS 31 +typedef struct{ + int partitions; /* 0 to 31 */ + int partitionclass[VIF_PARTS]; /* 0 to 15 */ + + int class_dim[VIF_CLASS]; /* 1 to 8 */ + int class_subs[VIF_CLASS]; /* 0,1,2,3 (bits: 1< +#include +#include "ogg.h" + +static unsigned long mask[]= +{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, + 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, + 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, + 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, + 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, + 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, + 0x3fffffff,0x7fffffff,0xffffffff }; + +/* mark read process as having run off the end */ +static void _adv_halt(oggpack_buffer *b){ + b->headptr=b->head->buffer->data+b->head->begin+b->head->length; + b->headend=-1; + b->headbit=0; +} + +/* spans forward, skipping as many bytes as headend is negative; if + headend is zero, simply finds next byte. If we're up to the end + of the buffer, leaves headend at zero. If we've read past the end, + halt the decode process. */ +static void _span(oggpack_buffer *b){ + while(b->headend<1){ + if(b->head->next){ + b->count+=b->head->length; + b->head=b->head->next; + b->headptr=b->head->buffer->data+b->head->begin-b->headend; + b->headend+=b->head->length; + }else{ + /* we've either met the end of decode, or gone past it. halt + only if we're past */ + if(b->headend<0 || b->headbit) + /* read has fallen off the end */ + _adv_halt(b); + + break; + } + } +} + +void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){ + memset(b,0,sizeof(*b)); + + b->tail=b->head=r; + b->count=0; + b->headptr=b->head->buffer->data+b->head->begin; + b->headend=b->head->length; + _span(b); +} + +#define _lookspan() while(!end){\ + head=head->next;\ + if(!head) return -1;\ + ptr=head->buffer->data + head->begin;\ + end=head->length;\ + } + +/* Read in bits without advancing the bitptr; bits <= 32 */ +long oggpack_look(oggpack_buffer *b,int bits){ + unsigned long m=mask[bits]; + unsigned long ret=-1; + + bits+=b->headbit; + + if(bits >= b->headend<<3){ + int end=b->headend; + unsigned char *ptr=b->headptr; + ogg_reference *head=b->head; + + if(end<0)return -1; + + if(bits){ + _lookspan(); + ret=*ptr++>>b->headbit; + if(bits>8){ + --end; + _lookspan(); + ret|=*ptr++<<(8-b->headbit); + if(bits>16){ + --end; + _lookspan(); + ret|=*ptr++<<(16-b->headbit); + if(bits>24){ + --end; + _lookspan(); + ret|=*ptr++<<(24-b->headbit); + if(bits>32 && b->headbit){ + --end; + _lookspan(); + ret|=*ptr<<(32-b->headbit); + } + } + } + } + } + + }else{ + + /* make this a switch jump-table */ + ret=b->headptr[0]>>b->headbit; + if(bits>8){ + ret|=b->headptr[1]<<(8-b->headbit); + if(bits>16){ + ret|=b->headptr[2]<<(16-b->headbit); + if(bits>24){ + ret|=b->headptr[3]<<(24-b->headbit); + if(bits>32 && b->headbit) + ret|=b->headptr[4]<<(32-b->headbit); + } + } + } + } + + ret&=m; + return ret; +} + +/* limited to 32 at a time */ +void oggpack_adv(oggpack_buffer *b,int bits){ + bits+=b->headbit; + b->headbit=bits&7; + b->headptr+=bits/8; + if((b->headend-=bits/8)<1)_span(b); +} + +/* spans forward and finds next byte. Never halts */ +static void _span_one(oggpack_buffer *b){ + while(b->headend<1){ + if(b->head->next){ + b->count+=b->head->length; + b->head=b->head->next; + b->headptr=b->head->buffer->data+b->head->begin; + b->headend=b->head->length; + }else + break; + } +} + +static int _halt_one(oggpack_buffer *b){ + if(b->headend<1){ + _adv_halt(b); + return -1; + } + return 0; +} + +int oggpack_eop(oggpack_buffer *b){ + if(b->headend<0)return -1; + return 0; +} + +/* bits <= 32 */ +long oggpack_read(oggpack_buffer *b,int bits){ + unsigned long m=mask[bits]; + ogg_uint32_t ret=-1; + + bits+=b->headbit; + + if(bits >= b->headend<<3){ + + if(b->headend<0)return -1; + + if(bits){ + if (_halt_one(b)) return -1; + ret=*b->headptr>>b->headbit; + + if(bits>=8){ + ++b->headptr; + --b->headend; + _span_one(b); + if(bits>8){ + if (_halt_one(b)) return -1; + ret|=*b->headptr<<(8-b->headbit); + + if(bits>=16){ + ++b->headptr; + --b->headend; + _span_one(b); + if(bits>16){ + if (_halt_one(b)) return -1; + ret|=*b->headptr<<(16-b->headbit); + + if(bits>=24){ + ++b->headptr; + --b->headend; + _span_one(b); + if(bits>24){ + if (_halt_one(b)) return -1; + ret|=*b->headptr<<(24-b->headbit); + + if(bits>=32){ + ++b->headptr; + --b->headend; + _span_one(b); + if(bits>32){ + if (_halt_one(b)) return -1; + if(b->headbit)ret|=*b->headptr<<(32-b->headbit); + + } + } + } + } + } + } + } + } + } + }else{ + + ret=b->headptr[0]>>b->headbit; + if(bits>8){ + ret|=b->headptr[1]<<(8-b->headbit); + if(bits>16){ + ret|=b->headptr[2]<<(16-b->headbit); + if(bits>24){ + ret|=b->headptr[3]<<(24-b->headbit); + if(bits>32 && b->headbit){ + ret|=b->headptr[4]<<(32-b->headbit); + } + } + } + } + + b->headptr+=bits/8; + b->headend-=bits/8; + } + + ret&=m; + b->headbit=bits&7; + return ret; +} + +long oggpack_bytes(oggpack_buffer *b){ + return(b->count+b->headptr-b->head->buffer->data-b->head->begin+ + (b->headbit+7)/8); +} + +long oggpack_bits(oggpack_buffer *b){ + return((b->count+b->headptr-b->head->buffer->data-b->head->begin)*8+ + b->headbit); +} + diff --git a/genplus-gx/core/tremor/block.c b/genplus-gx/core/tremor/block.c new file mode 100644 index 0000000000..8949253a16 --- /dev/null +++ b/genplus-gx/core/tremor/block.c @@ -0,0 +1,453 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: PCM data vector blocking, windowing and dis/reassembly + + ********************************************************************/ + +#include +#include +#include +#include "ogg.h" +#include "ivorbiscodec.h" +#include "codec_internal.h" + +#include "window.h" +#include "registry.h" +#include "misc.h" + +static int ilog(unsigned int v){ + int ret=0; + if(v)--v; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +/* pcm accumulator examples (not exhaustive): + + <-------------- lW ----------------> + <--------------- W ----------------> +: .....|..... _______________ | +: .''' | '''_--- | |\ | +:.....''' |_____--- '''......| | \_______| +:.................|__________________|_______|__|______| + |<------ Sl ------>| > Sr < |endW + |beginSl |endSl | |endSr + |beginW |endlW |beginSr + + + |< lW >| + <--------------- W ----------------> + | | .. ______________ | + | | ' `/ | ---_ | + |___.'___/`. | ---_____| + |_______|__|_______|_________________| + | >|Sl|< |<------ Sr ----->|endW + | | |endSl |beginSr |endSr + |beginW | |endlW + mult[0] |beginSl mult[n] + + <-------------- lW -----------------> + |<--W-->| +: .............. ___ | | +: .''' |`/ \ | | +:.....''' |/`....\|...| +:.........................|___|___|___| + |Sl |Sr |endW + | | |endSr + | |beginSr + | |endSl + |beginSl + |beginW +*/ + +/* block abstraction setup *********************************************/ + +#ifndef WORD_ALIGN +#define WORD_ALIGN 8 +#endif + +int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){ + memset(vb,0,sizeof(*vb)); + vb->vd=v; + vb->localalloc=0; + vb->localstore=NULL; + + return(0); +} + +void *_vorbis_block_alloc(vorbis_block *vb,long bytes){ + bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1); + if(bytes+vb->localtop>vb->localalloc){ + /* can't just _ogg_realloc... there are outstanding pointers */ + if(vb->localstore){ + struct alloc_chain *link=(struct alloc_chain *)_ogg_malloc(sizeof(*link)); + vb->totaluse+=vb->localtop; + link->next=vb->reap; + link->ptr=vb->localstore; + vb->reap=link; + } + /* highly conservative */ + vb->localalloc=bytes; + vb->localstore=_ogg_malloc(vb->localalloc); + vb->localtop=0; + } + { + void *ret=(void *)(((char *)vb->localstore)+vb->localtop); + vb->localtop+=bytes; + return ret; + } +} + +/* reap the chain, pull the ripcord */ +void _vorbis_block_ripcord(vorbis_block *vb){ + /* reap the chain */ + struct alloc_chain *reap=vb->reap; + while(reap){ + struct alloc_chain *next=reap->next; + _ogg_free(reap->ptr); + memset(reap,0,sizeof(*reap)); + _ogg_free(reap); + reap=next; + } + /* consolidate storage */ + if(vb->totaluse){ + vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc); + vb->localalloc+=vb->totaluse; + vb->totaluse=0; + } + + /* pull the ripcord */ + vb->localtop=0; + vb->reap=NULL; +} + +int vorbis_block_clear(vorbis_block *vb){ + _vorbis_block_ripcord(vb); + if(vb->localstore)_ogg_free(vb->localstore); + + memset(vb,0,sizeof(*vb)); + return(0); +} + +static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){ + int i; + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + private_state *b=NULL; + + memset(v,0,sizeof(*v)); + b=(private_state *)(v->backend_state=_ogg_calloc(1,sizeof(*b))); + + v->vi=vi; + b->modebits=ilog(ci->modes); + + /* Vorbis I uses only window type 0 */ + b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2); + b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2); + + /* finish the codebooks */ + if(!ci->fullbooks){ + ci->fullbooks=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); + for(i=0;ibooks;i++){ + vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]); + /* decode codebooks are now standalone after init */ + vorbis_staticbook_destroy(ci->book_param[i]); + ci->book_param[i]=NULL; + } + } + + v->pcm_storage=ci->blocksizes[1]; + v->pcm=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcm)); + v->pcmret=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcmret)); + for(i=0;ichannels;i++) + v->pcm[i]=(ogg_int32_t *)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i])); + + /* all 1 (large block) or 0 (small block) */ + /* explicitly set for the sake of clarity */ + v->lW=0; /* previous window size */ + v->W=0; /* current window size */ + + /* initialize all the mapping/backend lookups */ + b->mode=(vorbis_look_mapping **)_ogg_calloc(ci->modes,sizeof(*b->mode)); + for(i=0;imodes;i++){ + int mapnum=ci->mode_param[i]->mapping; + int maptype=ci->map_type[mapnum]; + b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i], + ci->map_param[mapnum]); + } + return(0); +} + +int vorbis_synthesis_restart(vorbis_dsp_state *v){ + vorbis_info *vi=v->vi; + codec_setup_info *ci; + + if(!v->backend_state)return -1; + if(!vi)return -1; + ci=vi->codec_setup; + if(!ci)return -1; + + v->centerW=ci->blocksizes[1]/2; + v->pcm_current=v->centerW; + + v->pcm_returned=-1; + v->granulepos=-1; + v->sequence=-1; + ((private_state *)(v->backend_state))->sample_count=-1; + + return(0); +} + +int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){ + _vds_init(v,vi); + vorbis_synthesis_restart(v); + + return(0); +} + +void vorbis_dsp_clear(vorbis_dsp_state *v){ + int i; + if(v){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL); + private_state *b=(private_state *)v->backend_state; + + if(v->pcm){ + for(i=0;ichannels;i++) + if(v->pcm[i])_ogg_free(v->pcm[i]); + _ogg_free(v->pcm); + if(v->pcmret)_ogg_free(v->pcmret); + } + + /* free mode lookups; these are actually vorbis_look_mapping structs */ + if(ci){ + for(i=0;imodes;i++){ + int mapnum=ci->mode_param[i]->mapping; + int maptype=ci->map_type[mapnum]; + if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]); + } + } + + if(b){ + if(b->mode)_ogg_free(b->mode); + _ogg_free(b); + } + + memset(v,0,sizeof(*v)); + } +} + +/* Unlike in analysis, the window is only partially applied for each + block. The time domain envelope is not yet handled at the point of + calling (as it relies on the previous block). */ + +int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + private_state *b=v->backend_state; + int i,j; + + if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL); + + v->lW=v->W; + v->W=vb->W; + v->nW=-1; + + if((v->sequence==-1)|| + (v->sequence+1 != vb->sequence)){ + v->granulepos=-1; /* out of sequence; lose count */ + b->sample_count=-1; + } + + v->sequence=vb->sequence; + + if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly + was called on block */ + int n=ci->blocksizes[v->W]/2; + int n0=ci->blocksizes[0]/2; + int n1=ci->blocksizes[1]/2; + + int thisCenter; + int prevCenter; + + if(v->centerW){ + thisCenter=n1; + prevCenter=0; + }else{ + thisCenter=0; + prevCenter=n1; + } + + /* v->pcm is now used like a two-stage double buffer. We don't want + to have to constantly shift *or* adjust memory usage. Don't + accept a new block until the old is shifted out */ + + /* overlap/add PCM */ + + for(j=0;jchannels;j++){ + /* the overlap/add section */ + if(v->lW){ + if(v->W){ + /* large/large */ + ogg_int32_t *pcm=v->pcm[j]+prevCenter; + ogg_int32_t *p=vb->pcm[j]; + for(i=0;ipcm[j]+prevCenter+n1/2-n0/2; + ogg_int32_t *p=vb->pcm[j]; + for(i=0;iW){ + /* small/large */ + ogg_int32_t *pcm=v->pcm[j]+prevCenter; + ogg_int32_t *p=vb->pcm[j]+n1/2-n0/2; + for(i=0;ipcm[j]+prevCenter; + ogg_int32_t *p=vb->pcm[j]; + for(i=0;ipcm[j]+thisCenter; + ogg_int32_t *p=vb->pcm[j]+n; + for(i=0;icenterW) + v->centerW=0; + else + v->centerW=n1; + + /* deal with initial packet state; we do this using the explicit + pcm_returned==-1 flag otherwise we're sensitive to first block + being short or long */ + + if(v->pcm_returned==-1){ + v->pcm_returned=thisCenter; + v->pcm_current=thisCenter; + }else{ + v->pcm_returned=prevCenter; + v->pcm_current=prevCenter+ + ci->blocksizes[v->lW]/4+ + ci->blocksizes[v->W]/4; + } + + } + + /* track the frame number... This is for convenience, but also + making sure our last packet doesn't end with added padding. If + the last packet is partial, the number of samples we'll have to + return will be past the vb->granulepos. + + This is not foolproof! It will be confused if we begin + decoding at the last page after a seek or hole. In that case, + we don't have a starting point to judge where the last frame + is. For this reason, vorbisfile will always try to make sure + it reads the last two marked pages in proper sequence */ + + if(b->sample_count==-1){ + b->sample_count=0; + }else{ + b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; + } + + if(v->granulepos==-1){ + if(vb->granulepos!=-1){ /* only set if we have a position to set to */ + + v->granulepos=vb->granulepos; + + /* is this a short page? */ + if(b->sample_count>v->granulepos){ + /* corner case; if this is both the first and last audio page, + then spec says the end is cut, not beginning */ + if(vb->eofflag){ + /* trim the end */ + /* no preceeding granulepos; assume we started at zero (we'd + have to in a short single-page stream) */ + /* granulepos could be -1 due to a seek, but that would result + in a long coun`t, not short count */ + + v->pcm_current-=(b->sample_count-v->granulepos); + }else{ + /* trim the beginning */ + v->pcm_returned+=(b->sample_count-v->granulepos); + if(v->pcm_returned>v->pcm_current) + v->pcm_returned=v->pcm_current; + } + + } + + } + }else{ + v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; + if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){ + + if(v->granulepos>vb->granulepos){ + long extra=v->granulepos-vb->granulepos; + + if(extra) + if(vb->eofflag){ + /* partial last frame. Strip the extra samples off */ + v->pcm_current-=extra; + } /* else {Shouldn't happen *unless* the bitstream is out of + spec. Either way, believe the bitstream } */ + } /* else {Shouldn't happen *unless* the bitstream is out of + spec. Either way, believe the bitstream } */ + v->granulepos=vb->granulepos; + } + } + + /* Update, cleanup */ + + if(vb->eofflag)v->eofflag=1; + return(0); +} + +/* pcm==NULL indicates we just want the pending samples, no more */ +int vorbis_synthesis_pcmout(vorbis_dsp_state *v,ogg_int32_t ***pcm){ + vorbis_info *vi=v->vi; + if(v->pcm_returned>-1 && v->pcm_returnedpcm_current){ + if(pcm){ + int i; + for(i=0;ichannels;i++) + v->pcmret[i]=v->pcm[i]+v->pcm_returned; + *pcm=v->pcmret; + } + return(v->pcm_current-v->pcm_returned); + } + return(0); +} + +int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){ + if(bytes && v->pcm_returned+bytes>v->pcm_current)return(OV_EINVAL); + v->pcm_returned+=bytes; + return(0); +} + diff --git a/genplus-gx/core/tremor/block.h b/genplus-gx/core/tremor/block.h new file mode 100644 index 0000000000..5e193543d4 --- /dev/null +++ b/genplus-gx/core/tremor/block.h @@ -0,0 +1,24 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2008 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: shared block functions + + ********************************************************************/ + +#ifndef _V_BLOCK_ +#define _V_BLOCK_ + +extern void _vorbis_block_ripcord(vorbis_block *vb); +extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes); + +#endif diff --git a/genplus-gx/core/tremor/codebook.c b/genplus-gx/core/tremor/codebook.c new file mode 100644 index 0000000000..d055870ad0 --- /dev/null +++ b/genplus-gx/core/tremor/codebook.c @@ -0,0 +1,371 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: basic codebook pack/unpack/code/decode operations + + ********************************************************************/ + +#include +#include +#include +#include "ogg.h" +#include "ivorbiscodec.h" +#include "codebook.h" +#include "misc.h" + +/* unpacks a codebook from the packet buffer into the codebook struct, + readies the codebook auxiliary structures for decode *************/ +int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){ + long i,j; + memset(s,0,sizeof(*s)); + + /* make sure alignment is correct */ + if(oggpack_read(opb,24)!=0x564342)goto _eofout; + + /* first the basic parameters */ + s->dim=oggpack_read(opb,16); + s->entries=oggpack_read(opb,24); + if(s->entries==-1)goto _eofout; + + /* codeword ordering.... length ordered or unordered? */ + switch((int)oggpack_read(opb,1)){ + case 0: + /* unordered */ + s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); + + /* allocated but unused entries? */ + if(oggpack_read(opb,1)){ + /* yes, unused entries */ + + for(i=0;ientries;i++){ + if(oggpack_read(opb,1)){ + long num=oggpack_read(opb,5); + if(num==-1)goto _eofout; + s->lengthlist[i]=num+1; + }else + s->lengthlist[i]=0; + } + }else{ + /* all entries used; no tagging */ + for(i=0;ientries;i++){ + long num=oggpack_read(opb,5); + if(num==-1)goto _eofout; + s->lengthlist[i]=num+1; + } + } + + break; + case 1: + /* ordered */ + { + long length=oggpack_read(opb,5)+1; + s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); + + for(i=0;ientries;){ + long num=oggpack_read(opb,_ilog(s->entries-i)); + if(num==-1)goto _eofout; + for(j=0;jentries;j++,i++) + s->lengthlist[i]=length; + length++; + } + } + break; + default: + /* EOF */ + return(-1); + } + + /* Do we have a mapping to unpack? */ + switch((s->maptype=oggpack_read(opb,4))){ + case 0: + /* no mapping */ + break; + case 1: case 2: + /* implicitly populated value mapping */ + /* explicitly populated value mapping */ + + s->q_min=oggpack_read(opb,32); + s->q_delta=oggpack_read(opb,32); + s->q_quant=oggpack_read(opb,4)+1; + s->q_sequencep=oggpack_read(opb,1); + + { + int quantvals=0; + switch(s->maptype){ + case 1: + quantvals=_book_maptype1_quantvals(s); + break; + case 2: + quantvals=s->entries*s->dim; + break; + } + + /* quantized values */ + s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals); + for(i=0;iquantlist[i]=oggpack_read(opb,s->q_quant); + + if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout; + } + break; + default: + goto _errout; + } + + /* all set */ + return(0); + + _errout: + _eofout: + vorbis_staticbook_clear(s); + return(-1); +} + +/* the 'eliminate the decode tree' optimization actually requires the + codewords to be MSb first, not LSb. This is an annoying inelegancy + (and one of the first places where carefully thought out design + turned out to be wrong; Vorbis II and future Ogg codecs should go + to an MSb bitpacker), but not actually the huge hit it appears to + be. The first-stage decode table catches most words so that + bitreverse is not in the main execution path. */ + +static ogg_uint32_t bitreverse(ogg_uint32_t x){ + x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000); + x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00); + x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0); + x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc); + return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa); +} + +STIN long decode_packed_entry_number(codebook *book, + oggpack_buffer *b){ + int read=book->dec_maxlength; + long lo,hi; + long lok = oggpack_look(b,book->dec_firsttablen); + + if (lok >= 0) { + long entry = book->dec_firsttable[lok]; + if(entry&0x80000000UL){ + lo=(entry>>15)&0x7fff; + hi=book->used_entries-(entry&0x7fff); + }else{ + oggpack_adv(b, book->dec_codelengths[entry-1]); + return(entry-1); + } + }else{ + lo=0; + hi=book->used_entries; + } + + lok = oggpack_look(b, read); + + while(lok<0 && read>1) + lok = oggpack_look(b, --read); + + if(lok<0){ + oggpack_adv(b,1); /* force eop */ + return -1; + } + + /* bisect search for the codeword in the ordered list */ + { + ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok); + + while(hi-lo>1){ + long p=(hi-lo)>>1; + long test=book->codelist[lo+p]>testword; + lo+=p&(test-1); + hi-=p&(-test); + } + + if(book->dec_codelengths[lo]<=read){ + oggpack_adv(b, book->dec_codelengths[lo]); + return(lo); + } + } + + oggpack_adv(b, read+1); + return(-1); +} + +/* Decode side is specced and easier, because we don't need to find + matches using different criteria; we simply read and map. There are + two things we need to do 'depending': + + We may need to support interleave. We don't really, but it's + convenient to do it here rather than rebuild the vector later. + + Cascades may be additive or multiplicitive; this is not inherent in + the codebook, but set in the code using the codebook. Like + interleaving, it's easiest to do it here. + addmul==0 -> declarative (set the value) + addmul==1 -> additive + addmul==2 -> multiplicitive */ + +/* returns the [original, not compacted] entry number or -1 on eof *********/ +long vorbis_book_decode(codebook *book, oggpack_buffer *b){ + if(book->used_entries>0){ + long packed_entry=decode_packed_entry_number(book,b); + if(packed_entry>=0) + return(book->dec_index[packed_entry]); + } + + /* if there's no dec_index, the codebook unpacking isn't collapsed */ + return(-1); +} + +/* returns 0 on OK or -1 on eof *************************************/ +long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, + oggpack_buffer *b,int n,int point){ + if(book->used_entries>0){ + int step=n/book->dim; + long *entry = (long *)alloca(sizeof(*entry)*step); + ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step); + int i,j,o; + int shift=point-book->binarypoint; + + if(shift>=0){ + for (i = 0; i < step; i++) { + entry[i]=decode_packed_entry_number(book,b); + if(entry[i]==-1)return(-1); + t[i] = book->valuelist+entry[i]*book->dim; + } + for(i=0,o=0;idim;i++,o+=step) + for (j=0;j>shift; + }else{ + for (i = 0; i < step; i++) { + entry[i]=decode_packed_entry_number(book,b); + if(entry[i]==-1)return(-1); + t[i] = book->valuelist+entry[i]*book->dim; + } + for(i=0,o=0;idim;i++,o+=step) + for (j=0;jused_entries>0){ + int i,j,entry; + ogg_int32_t *t; + int shift=point-book->binarypoint; + + if(shift>=0){ + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;) + a[i++]+=t[j++]>>shift; + } + }else{ + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;) + a[i++]+=t[j++]<<-shift; + } + } + } + return(0); +} + +long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, + oggpack_buffer *b,int n,int point){ + if(book->used_entries>0){ + int i,j,entry; + ogg_int32_t *t; + int shift=point-book->binarypoint; + + if(shift>=0){ + + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;){ + a[i++]=t[j++]>>shift; + } + } + }else{ + + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;){ + a[i++]=t[j++]<<-shift; + } + } + } + }else{ + + int i,j; + for(i=0;idim;){ + a[i++]=0; + } + } + } + return(0); +} + +long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,\ + long offset,int ch, + oggpack_buffer *b,int n,int point){ + if(book->used_entries>0){ + long i,j,entry; + int chptr=0; + int shift=point-book->binarypoint; + + if(shift>=0){ + + for(i=offset;ivaluelist+entry*book->dim; + for (j=0;jdim;j++){ + a[chptr++][i]+=t[j]>>shift; + if(chptr==ch){ + chptr=0; + i++; + } + } + } + } + }else{ + + for(i=offset;ivaluelist+entry*book->dim; + for (j=0;jdim;j++){ + a[chptr++][i]+=t[j]<<-shift; + if(chptr==ch){ + chptr=0; + i++; + } + } + } + } + } + } + return(0); +} diff --git a/genplus-gx/core/tremor/codebook.h b/genplus-gx/core/tremor/codebook.h new file mode 100644 index 0000000000..14f65382dd --- /dev/null +++ b/genplus-gx/core/tremor/codebook.h @@ -0,0 +1,102 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: basic shared codebook operations + + ********************************************************************/ + +#ifndef _V_CODEBOOK_H_ +#define _V_CODEBOOK_H_ + +#include "ogg.h" + +/* This structure encapsulates huffman and VQ style encoding books; it + doesn't do anything specific to either. + + valuelist/quantlist are nonNULL (and q_* significant) only if + there's entry->value mapping to be done. + + If encode-side mapping must be done (and thus the entry needs to be + hunted), the auxiliary encode pointer will point to a decision + tree. This is true of both VQ and huffman, but is mostly useful + with VQ. + +*/ + +typedef struct static_codebook{ + long dim; /* codebook dimensions (elements per vector) */ + long entries; /* codebook entries */ + long *lengthlist; /* codeword lengths in bits */ + + /* mapping ***************************************************************/ + int maptype; /* 0=none + 1=implicitly populated values from map column + 2=listed arbitrary values */ + + /* The below does a linear, single monotonic sequence mapping. */ + long q_min; /* packed 32 bit float; quant value 0 maps to minval */ + long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */ + int q_quant; /* bits: 0 < quant <= 16 */ + int q_sequencep; /* bitflag */ + + long *quantlist; /* map == 1: (int)(entries^(1/dim)) element column map + map == 2: list of dim*entries quantized entry vals + */ +} static_codebook; + +typedef struct codebook{ + long dim; /* codebook dimensions (elements per vector) */ + long entries; /* codebook entries */ + long used_entries; /* populated codebook entries */ + + /* the below are ordered by bitreversed codeword and only used + entries are populated */ + int binarypoint; + ogg_int32_t *valuelist; /* list of dim*entries actual entry values */ + ogg_uint32_t *codelist; /* list of bitstream codewords for each entry */ + + int *dec_index; + char *dec_codelengths; + ogg_uint32_t *dec_firsttable; + int dec_firsttablen; + int dec_maxlength; + + long q_min; /* packed 32 bit float; quant value 0 maps to minval */ + long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */ + +} codebook; + +extern void vorbis_staticbook_clear(static_codebook *b); +extern void vorbis_staticbook_destroy(static_codebook *b); +extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source); + +extern void vorbis_book_clear(codebook *b); +extern long _book_maptype1_quantvals(const static_codebook *b); + +extern int vorbis_staticbook_unpack(oggpack_buffer *b,static_codebook *c); + +extern long vorbis_book_decode(codebook *book, oggpack_buffer *b); +extern long vorbis_book_decodevs_add(codebook *book, ogg_int32_t *a, + oggpack_buffer *b,int n,int point); +extern long vorbis_book_decodev_set(codebook *book, ogg_int32_t *a, + oggpack_buffer *b,int n,int point); +extern long vorbis_book_decodev_add(codebook *book, ogg_int32_t *a, + oggpack_buffer *b,int n,int point); +extern long vorbis_book_decodevv_add(codebook *book, ogg_int32_t **a, + long off,int ch, + oggpack_buffer *b,int n,int point); + +extern int _ilog(unsigned int v); + + +#endif diff --git a/genplus-gx/core/tremor/codec_internal.h b/genplus-gx/core/tremor/codec_internal.h new file mode 100644 index 0000000000..3ca7f54724 --- /dev/null +++ b/genplus-gx/core/tremor/codec_internal.h @@ -0,0 +1,92 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: libvorbis codec headers + + ********************************************************************/ + +#ifndef _V_CODECI_H_ +#define _V_CODECI_H_ + +#include "codebook.h" + +typedef void vorbis_look_mapping; +typedef void vorbis_look_floor; +typedef void vorbis_look_residue; +typedef void vorbis_look_transform; + +/* mode ************************************************************/ +typedef struct { + int blockflag; + int windowtype; + int transformtype; + int mapping; +} vorbis_info_mode; + +typedef void vorbis_info_floor; +typedef void vorbis_info_residue; +typedef void vorbis_info_mapping; + +typedef struct private_state { + /* local lookup storage */ + const void *window[2]; + + /* backend lookups are tied to the mode, not the backend or naked mapping */ + int modebits; + vorbis_look_mapping **mode; + + ogg_int64_t sample_count; + +} private_state; + +/* codec_setup_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). +*********************************************************************/ + +typedef struct codec_setup_info { + + /* Vorbis supports only short and long blocks, but allows the + encoder to choose the sizes */ + + long blocksizes[2]; + + /* modes are the primary means of supporting on-the-fly different + blocksizes, different channel mappings (LR or M/A), + different residue backends, etc. Each mode consists of a + blocksize flag and a mapping (along with the mapping setup */ + + int modes; + int maps; + int times; + int floors; + int residues; + int books; + + vorbis_info_mode *mode_param[64]; + int map_type[64]; + vorbis_info_mapping *map_param[64]; + int time_type[64]; + int floor_type[64]; + vorbis_info_floor *floor_param[64]; + int residue_type[64]; + vorbis_info_residue *residue_param[64]; + static_codebook *book_param[256]; + codebook *fullbooks; + + int passlimit[32]; /* iteration limit per couple/quant pass */ + int coupling_passes; +} codec_setup_info; + +#endif diff --git a/genplus-gx/core/tremor/config_types.h b/genplus-gx/core/tremor/config_types.h new file mode 100644 index 0000000000..1fdcb27fe7 --- /dev/null +++ b/genplus-gx/core/tremor/config_types.h @@ -0,0 +1,25 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + + ********************************************************************/ +#ifndef _OS_CVTYPES_H +#define _OS_CVTYPES_H + +typedef long long ogg_int64_t; +typedef int ogg_int32_t; +typedef unsigned int ogg_uint32_t; +typedef short ogg_int16_t; + +#endif diff --git a/genplus-gx/core/tremor/configure.in b/genplus-gx/core/tremor/configure.in new file mode 100644 index 0000000000..2b44ee4a26 --- /dev/null +++ b/genplus-gx/core/tremor/configure.in @@ -0,0 +1,131 @@ +dnl Process this file with autoconf to produce a configure script + +dnl ------------------------------------------------ +dnl Initialization and Versioning +dnl ------------------------------------------------ + +AC_INIT(mdct.c) + +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +AM_CONFIG_HEADER([config.h]) + +AM_INIT_AUTOMAKE(libvorbisidec,1.2.0) + +dnl Library versioning + +V_LIB_CURRENT=1 +V_LIB_REVISION=2 +V_LIB_AGE=0 +AC_SUBST(V_LIB_CURRENT) +AC_SUBST(V_LIB_REVISION) +AC_SUBST(V_LIB_AGE) + +dnl -------------------------------------------------- +dnl Check for programs +dnl -------------------------------------------------- + +dnl save $CFLAGS since AC_PROG_CC likes to insert "-g -O2" +dnl if $CFLAGS is blank +cflags_save="$CFLAGS" +AC_PROG_CC +AC_PROG_CPP +CFLAGS="$cflags_save" + +AM_PROG_LIBTOOL + +dnl -------------------------------------------------- +dnl Set build flags based on environment +dnl -------------------------------------------------- + +dnl Set some target options + +cflags_save="$CFLAGS" +ldflags_save="$LDFLAGS" +if test -z "$GCC"; then + case $host in + arm-*-*) + DEBUG="-g -D_ARM_ASSEM_" + CFLAGS="-O -D_ARM_ASSEM_" + PROFILE="-p -g -O -D_ARM_ASSEM_" ;; + *) + DEBUG="-g" + CFLAGS="-O" + PROFILE="-g -p" ;; + esac +else + + case $host in + arm-*-*) + DEBUG="-g -Wall -D__NO_MATH_INLINES -fsigned-char -D_ARM_ASSEM_" + CFLAGS="-O2 -D_ARM_ASSEM_ -fsigned-char" + PROFILE="-W -pg -g -O2 -D_ARM_ASSEM_ -fsigned-char -fno-inline-functions";; + + *) + DEBUG="-g -Wall -D__NO_MATH_INLINES -fsigned-char" + CFLAGS="-O2 -Wall -fsigned-char" + PROFILE="-Wall -pg -g -O2 -fsigned-char -fno-inline-functions";; + esac +fi +CFLAGS="$CFLAGS $cflags_save -D_REENTRANT" +LDFLAGS="$LDFLAGS $ldflags_save" + + +# Test whenever ld supports -version-script +AC_PROG_LD +AC_PROG_LD_GNU +if test "x$lt_cv_prog_gnu_ld" = "xyes"; then + SHLIB_VERSION_ARG="Wl,--version-script=Version_script" + + dnl Set extra linker options + case "$target_os" in + linux* | solaris* ) + SHLIB_VERSION_ARG="-Wl,--version-script=Version_script" + ;; + *) + ;; + esac + LDFLAGS="$LDFLAGS $SHLIB_VERSION_ARG" +fi + +dnl -------------------------------------------------- +dnl Options +dnl -------------------------------------------------- + +AC_ARG_ENABLE( + low-accuracy, + [ --enable-low-accuracy enable 32 bit only multiply operations], + CFLAGS="$CFLAGS -D_LOW_ACCURACY_" +) + +dnl -------------------------------------------------- +dnl Check for headers +dnl -------------------------------------------------- + +AC_CHECK_HEADER(memory.h,CFLAGS="$CFLAGS -DUSE_MEMORY_H",:) + +dnl -------------------------------------------------- +dnl Check for typedefs, structures, etc +dnl -------------------------------------------------- + +dnl none + +dnl -------------------------------------------------- +dnl Check for library functions +dnl -------------------------------------------------- + +AC_FUNC_ALLOCA +AC_FUNC_MEMCMP + +dnl -------------------------------------------------- +dnl Do substitutions +dnl -------------------------------------------------- + +LIBS="$LIBS" + +AC_SUBST(LIBS) +AC_SUBST(DEBUG) +AC_SUBST(PROFILE) + +AC_OUTPUT(Makefile Version_script) diff --git a/genplus-gx/core/tremor/floor0.c b/genplus-gx/core/tremor/floor0.c new file mode 100644 index 0000000000..bdb83b8527 --- /dev/null +++ b/genplus-gx/core/tremor/floor0.c @@ -0,0 +1,435 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: floor backend 0 implementation + + ********************************************************************/ + +#include +#include +#include +#include "ogg.h" +#include "ivorbiscodec.h" +#include "codec_internal.h" +#include "registry.h" +#include "codebook.h" +#include "misc.h" +#include "block.h" + +#define LSP_FRACBITS 14 + +typedef struct { + long n; + int ln; + int m; + int *linearmap; + + vorbis_info_floor0 *vi; + ogg_int32_t *lsp_look; + +} vorbis_look_floor0; + +/*************** LSP decode ********************/ + +#include "lsp_lookup.h" + +/* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in + 16.16 format + returns in m.8 format */ + +static long ADJUST_SQRT2[2]={8192,5792}; +STIN ogg_int32_t vorbis_invsqlook_i(long a,long e){ + long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1); + long d=a&INVSQ_LOOKUP_I_MASK; /* 0.10 */ + long val=INVSQ_LOOKUP_I[i]- /* 1.16 */ + ((INVSQ_LOOKUP_IDel[i]*d)>>INVSQ_LOOKUP_I_SHIFT); /* result 1.16 */ + val*=ADJUST_SQRT2[e&1]; + e=(e>>1)+21; + return(val>>e); +} + +/* interpolated lookup based fromdB function, domain -140dB to 0dB only */ +/* a is in n.12 format */ +STIN ogg_int32_t vorbis_fromdBlook_i(long a){ + int i=(-a)>>(12-FROMdB2_SHIFT); + if(i<0) return 0x7fffffff; + if(i>=(FROMdB_LOOKUP_SZ<>FROMdB_SHIFT] * FROMdB2_LOOKUP[i&FROMdB2_MASK]; +} + +/* interpolated lookup based cos function, domain 0 to PI only */ +/* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */ +STIN ogg_int32_t vorbis_coslook_i(long a){ + int i=a>>COS_LOOKUP_I_SHIFT; + int d=a&COS_LOOKUP_I_MASK; + return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>> + COS_LOOKUP_I_SHIFT); +} + +/* interpolated lookup based cos function */ +/* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */ +STIN ogg_int32_t vorbis_coslook2_i(long a){ + a=a&0x1ffff; + + if(a>0x10000)a=0x20000-a; + { + int i=a>>COS_LOOKUP_I_SHIFT; + int d=a&COS_LOOKUP_I_MASK; + a=((COS_LOOKUP_I[i]<> + (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14); + } + + return(a); +} + +static const int barklook[28]={ + 0,100,200,301, 405,516,635,766, + 912,1077,1263,1476, 1720,2003,2333,2721, + 3184,3742,4428,5285, 6376,7791,9662,12181, + 15624,20397,27087,36554 +}; + +/* used in init only; interpolate the long way */ +STIN ogg_int32_t toBARK(int n){ + int i; + for(i=0;i<27;i++) + if(n>=barklook[i] && n>10)*0x517d)>>14; +#endif + + /* safeguard against a malicious stream */ + if(val<0 || (val>>COS_LOOKUP_I_SHIFT)>=COS_LOOKUP_I_SZ){ + memset(curve,0,sizeof(*curve)*n); + return; + } + + ilsp[i]=vorbis_coslook_i(val); + } + + i=0; + while(i>16); + qi=((qi*qi)>>16); + + if(m&1){ + qexp= qexp*2-28*((m+1)>>1)+m; + pi*=(1<<14)-((wi*wi)>>14); + qi+=pi>>14; + }else{ + qexp= qexp*2-13*m; + + pi*=(1<<14)-wi; + qi*=(1<<14)+wi; + + qi=(qi+pi)>>14; + } + + if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */ + qi>>=1; qexp++; + }else + lsp_norm_asm(&qi,&qexp); + +#else + + qi*=labs(ilsp[0]-wi); + pi*=labs(ilsp[1]-wi); + + for(j=3;j>25])) + if(!(shift=MLOOP_2[(pi|qi)>>19])) + shift=MLOOP_3[(pi|qi)>>16]; + qi=(qi>>shift)*labs(ilsp[j-1]-wi); + pi=(pi>>shift)*labs(ilsp[j]-wi); + qexp+=shift; + } + if(!(shift=MLOOP_1[(pi|qi)>>25])) + if(!(shift=MLOOP_2[(pi|qi)>>19])) + shift=MLOOP_3[(pi|qi)>>16]; + + /* pi,qi normalized collectively, both tracked using qexp */ + + if(m&1){ + /* odd order filter; slightly assymetric */ + /* the last coefficient */ + qi=(qi>>shift)*labs(ilsp[j-1]-wi); + pi=(pi>>shift)<<14; + qexp+=shift; + + if(!(shift=MLOOP_1[(pi|qi)>>25])) + if(!(shift=MLOOP_2[(pi|qi)>>19])) + shift=MLOOP_3[(pi|qi)>>16]; + + pi>>=shift; + qi>>=shift; + qexp+=shift-14*((m+1)>>1); + + pi=((pi*pi)>>16); + qi=((qi*qi)>>16); + qexp=qexp*2+m; + + pi*=(1<<14)-((wi*wi)>>14); + qi+=pi>>14; + + }else{ + /* even order filter; still symmetric */ + + /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't + worth tracking step by step */ + + pi>>=shift; + qi>>=shift; + qexp+=shift-7*m; + + pi=((pi*pi)>>16); + qi=((qi*qi)>>16); + qexp=qexp*2+m; + + pi*=(1<<14)-wi; + qi*=(1<<14)+wi; + qi=(qi+pi)>>14; + + } + + + /* we've let the normalization drift because it wasn't important; + however, for the lookup, things must be normalized again. We + need at most one right shift or a number of left shifts */ + + if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */ + qi>>=1; qexp++; + }else + while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/ + qi<<=1; qexp--; + } + +#endif + + amp=vorbis_fromdBlook_i(ampi* /* n.4 */ + vorbis_invsqlook_i(qi,qexp)- + /* m.8, m+n<=8 */ + ampoffseti); /* 8.12[0] */ + +#ifdef _LOW_ACCURACY_ + amp>>=9; +#endif + curve[i]= MULT31_SHIFT15(curve[i],amp); + while(map[++i]==k) curve[i]= MULT31_SHIFT15(curve[i],amp); + } +} + +/*************** vorbis decode glue ************/ + +static void floor0_free_info(vorbis_info_floor *i){ + vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +static void floor0_free_look(vorbis_look_floor *i){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + if(look){ + + if(look->linearmap)_ogg_free(look->linearmap); + if(look->lsp_look)_ogg_free(look->lsp_look); + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + int j; + + vorbis_info_floor0 *info=(vorbis_info_floor0 *)_ogg_malloc(sizeof(*info)); + info->order=oggpack_read(opb,8); + info->rate=oggpack_read(opb,16); + info->barkmap=oggpack_read(opb,16); + info->ampbits=oggpack_read(opb,6); + info->ampdB=oggpack_read(opb,8); + info->numbooks=oggpack_read(opb,4)+1; + + if(info->order<1)goto err_out; + if(info->rate<1)goto err_out; + if(info->barkmap<1)goto err_out; + if(info->numbooks<1)goto err_out; + + for(j=0;jnumbooks;j++){ + info->books[j]=oggpack_read(opb,8); + if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out; + } + return(info); + + err_out: + floor0_free_info(info); + return(NULL); +} + +/* initialize Bark scale and normalization lookups. We could do this + with static tables, but Vorbis allows a number of possible + combinations, so it's best to do it computationally. + + The below is authoritative in terms of defining scale mapping. + Note that the scale depends on the sampling rate as well as the + linear block and mapping sizes */ + +static vorbis_look_floor *floor0_look (vorbis_dsp_state *vd,vorbis_info_mode *mi, + vorbis_info_floor *i){ + int j; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; + vorbis_look_floor0 *look=(vorbis_look_floor0 *)_ogg_calloc(1,sizeof(*look)); + look->m=info->order; + look->n=ci->blocksizes[mi->blockflag]/2; + look->ln=info->barkmap; + look->vi=info; + + /* the mapping from a linear scale to a smaller bark scale is + straightforward. We do *not* make sure that the linear mapping + does not skip bark-scale bins; the decoder simply skips them and + the encoder may do what it wishes in filling them. They're + necessary in some mapping combinations to keep the scale spacing + accurate */ + look->linearmap=(int *)_ogg_malloc((look->n+1)*sizeof(*look->linearmap)); + for(j=0;jn;j++){ + + int val=(look->ln* + ((toBARK(info->rate/2*j/look->n)<<11)/toBARK(info->rate/2)))>>11; + + if(val>=look->ln)val=look->ln-1; /* guard against the approximation */ + look->linearmap[j]=val; + } + look->linearmap[j]=-1; + + look->lsp_look=(ogg_int32_t *)_ogg_malloc(look->ln*sizeof(*look->lsp_look)); + for(j=0;jln;j++) + look->lsp_look[j]=vorbis_coslook2_i(0x10000*j/look->ln); + + return look; +} + +static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + vorbis_info_floor0 *info=look->vi; + int j,k; + + int ampraw=oggpack_read(&vb->opb,info->ampbits); + if(ampraw>0){ /* also handles the -1 out of data case */ + long maxval=(1<ampbits)-1; + int amp=((ampraw*info->ampdB)<<4)/maxval; + int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); + + if(booknum!=-1 && booknumnumbooks){ /* be paranoid */ + codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup; + codebook *b=ci->fullbooks+info->books[booknum]; + ogg_int32_t last=0; + ogg_int32_t *lsp=(ogg_int32_t *)_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+1)); + + for(j=0;jm;j+=b->dim) + if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim,-24)==-1)goto eop; + for(j=0;jm;){ + for(k=0;kdim;k++,j++)lsp[j]+=last; + last=lsp[j-1]; + } + + lsp[look->m]=amp; + return(lsp); + } + } + eop: + return(NULL); +} + +static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i, + void *memo,ogg_int32_t *out){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + vorbis_info_floor0 *info=look->vi; + + if(memo){ + ogg_int32_t *lsp=(ogg_int32_t *)memo; + ogg_int32_t amp=lsp[look->m]; + + /* take the coefficients back to a spectral envelope curve */ + vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln, + lsp,look->m,amp,info->ampdB,look->lsp_look); + return(1); + } + memset(out,0,sizeof(*out)*look->n); + return(0); +} + +/* export hooks */ +vorbis_func_floor floor0_exportbundle={ + &floor0_unpack,&floor0_look,&floor0_free_info, + &floor0_free_look,&floor0_inverse1,&floor0_inverse2 +}; + + diff --git a/genplus-gx/core/tremor/floor1.c b/genplus-gx/core/tremor/floor1.c new file mode 100644 index 0000000000..276ed8d8a8 --- /dev/null +++ b/genplus-gx/core/tremor/floor1.c @@ -0,0 +1,441 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: floor backend 1 implementation + + ********************************************************************/ + +#include +#include +#include +#include "ogg.h" +#include "ivorbiscodec.h" +#include "codec_internal.h" +#include "registry.h" +#include "codebook.h" +#include "misc.h" +#include "block.h" + +#define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */ + +typedef struct { + int forward_index[VIF_POSIT+2]; + + int hineighbor[VIF_POSIT]; + int loneighbor[VIF_POSIT]; + int posts; + + int n; + int quant_q; + vorbis_info_floor1 *vi; + +} vorbis_look_floor1; + +/***********************************************/ + +static void floor1_free_info(vorbis_info_floor *i){ + vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +static void floor1_free_look(vorbis_look_floor *i){ + vorbis_look_floor1 *look=(vorbis_look_floor1 *)i; + if(look){ + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +static int ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + int j,k,count=0,maxclass=-1,rangebits; + + vorbis_info_floor1 *info=(vorbis_info_floor1 *)_ogg_calloc(1,sizeof(*info)); + /* read partitions */ + info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */ + for(j=0;jpartitions;j++){ + info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */ + if(maxclasspartitionclass[j])maxclass=info->partitionclass[j]; + } + + /* read partition classes */ + for(j=0;jclass_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */ + info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */ + if(info->class_subs[j]<0) + goto err_out; + if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8); + if(info->class_book[j]<0 || info->class_book[j]>=ci->books) + goto err_out; + for(k=0;k<(1<class_subs[j]);k++){ + info->class_subbook[j][k]=oggpack_read(opb,8)-1; + if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books) + goto err_out; + } + } + + /* read the post list */ + info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */ + rangebits=oggpack_read(opb,4); + + for(j=0,k=0;jpartitions;j++){ + count+=info->class_dim[info->partitionclass[j]]; + for(;kpostlist[k+2]=oggpack_read(opb,rangebits); + if(t<0 || t>=(1<postlist[0]=0; + info->postlist[1]=1<vi=info; + look->n=info->postlist[1]; + + /* we drop each position value in-between already decoded values, + and use linear interpolation to predict each new value past the + edges. The positions are read in the order of the position + list... we precompute the bounding positions in the lookup. Of + course, the neighbors can change (if a position is declined), but + this is an initial mapping */ + + for(i=0;ipartitions;i++)n+=info->class_dim[info->partitionclass[i]]; + n+=2; + look->posts=n; + + /* also store a sorted position index */ + for(i=0;ipostlist+i; + qsort(sortpointer,n,sizeof(*sortpointer),icomp); + + /* points from sort order back to range number */ + for(i=0;iforward_index[i]=sortpointer[i]-info->postlist; + + /* quantize values to multiplier spec */ + switch(info->mult){ + case 1: /* 1024 -> 256 */ + look->quant_q=256; + break; + case 2: /* 1024 -> 128 */ + look->quant_q=128; + break; + case 3: /* 1024 -> 86 */ + look->quant_q=86; + break; + case 4: /* 1024 -> 64 */ + look->quant_q=64; + break; + } + + /* discover our neighbors for decode where we don't use fit flags + (that would push the neighbors outward) */ + for(i=0;in; + int currentx=info->postlist[i+2]; + for(j=0;jpostlist[j]; + if(x>lx && xcurrentx){ + hi=j; + hx=x; + } + } + look->loneighbor[i]=lo; + look->hineighbor[i]=hi; + } + + return(look); +} + +static int render_point(int x0,int x1,int y0,int y1,int x){ + y0&=0x7fff; /* mask off flag */ + y1&=0x7fff; + + { + int dy=y1-y0; + int adx=x1-x0; + int ady=abs(dy); + int err=ady*(x-x0); + + int off=err/adx; + if(dy<0)return(y0-off); + return(y0+off); + } +} + +#ifdef _LOW_ACCURACY_ +# define XdB(n) ((((n)>>8)+1)>>1) +#else +# define XdB(n) (n) +#endif + +static const ogg_int32_t FLOOR_fromdB_LOOKUP[256]={ + XdB(0x000000e5), XdB(0x000000f4), XdB(0x00000103), XdB(0x00000114), + XdB(0x00000126), XdB(0x00000139), XdB(0x0000014e), XdB(0x00000163), + XdB(0x0000017a), XdB(0x00000193), XdB(0x000001ad), XdB(0x000001c9), + XdB(0x000001e7), XdB(0x00000206), XdB(0x00000228), XdB(0x0000024c), + XdB(0x00000272), XdB(0x0000029b), XdB(0x000002c6), XdB(0x000002f4), + XdB(0x00000326), XdB(0x0000035a), XdB(0x00000392), XdB(0x000003cd), + XdB(0x0000040c), XdB(0x00000450), XdB(0x00000497), XdB(0x000004e4), + XdB(0x00000535), XdB(0x0000058c), XdB(0x000005e8), XdB(0x0000064a), + XdB(0x000006b3), XdB(0x00000722), XdB(0x00000799), XdB(0x00000818), + XdB(0x0000089e), XdB(0x0000092e), XdB(0x000009c6), XdB(0x00000a69), + XdB(0x00000b16), XdB(0x00000bcf), XdB(0x00000c93), XdB(0x00000d64), + XdB(0x00000e43), XdB(0x00000f30), XdB(0x0000102d), XdB(0x0000113a), + XdB(0x00001258), XdB(0x0000138a), XdB(0x000014cf), XdB(0x00001629), + XdB(0x0000179a), XdB(0x00001922), XdB(0x00001ac4), XdB(0x00001c82), + XdB(0x00001e5c), XdB(0x00002055), XdB(0x0000226f), XdB(0x000024ac), + XdB(0x0000270e), XdB(0x00002997), XdB(0x00002c4b), XdB(0x00002f2c), + XdB(0x0000323d), XdB(0x00003581), XdB(0x000038fb), XdB(0x00003caf), + XdB(0x000040a0), XdB(0x000044d3), XdB(0x0000494c), XdB(0x00004e10), + XdB(0x00005323), XdB(0x0000588a), XdB(0x00005e4b), XdB(0x0000646b), + XdB(0x00006af2), XdB(0x000071e5), XdB(0x0000794c), XdB(0x0000812e), + XdB(0x00008993), XdB(0x00009283), XdB(0x00009c09), XdB(0x0000a62d), + XdB(0x0000b0f9), XdB(0x0000bc79), XdB(0x0000c8b9), XdB(0x0000d5c4), + XdB(0x0000e3a9), XdB(0x0000f274), XdB(0x00010235), XdB(0x000112fd), + XdB(0x000124dc), XdB(0x000137e4), XdB(0x00014c29), XdB(0x000161bf), + XdB(0x000178bc), XdB(0x00019137), XdB(0x0001ab4a), XdB(0x0001c70e), + XdB(0x0001e4a1), XdB(0x0002041f), XdB(0x000225aa), XdB(0x00024962), + XdB(0x00026f6d), XdB(0x000297f0), XdB(0x0002c316), XdB(0x0002f109), + XdB(0x000321f9), XdB(0x00035616), XdB(0x00038d97), XdB(0x0003c8b4), + XdB(0x000407a7), XdB(0x00044ab2), XdB(0x00049218), XdB(0x0004de23), + XdB(0x00052f1e), XdB(0x0005855c), XdB(0x0005e135), XdB(0x00064306), + XdB(0x0006ab33), XdB(0x00071a24), XdB(0x0007904b), XdB(0x00080e20), + XdB(0x00089422), XdB(0x000922da), XdB(0x0009bad8), XdB(0x000a5cb6), + XdB(0x000b091a), XdB(0x000bc0b1), XdB(0x000c8436), XdB(0x000d5471), + XdB(0x000e3233), XdB(0x000f1e5f), XdB(0x001019e4), XdB(0x001125c1), + XdB(0x00124306), XdB(0x001372d5), XdB(0x0014b663), XdB(0x00160ef7), + XdB(0x00177df0), XdB(0x001904c1), XdB(0x001aa4f9), XdB(0x001c603d), + XdB(0x001e384f), XdB(0x00202f0f), XdB(0x0022467a), XdB(0x002480b1), + XdB(0x0026dff7), XdB(0x002966b3), XdB(0x002c1776), XdB(0x002ef4fc), + XdB(0x0032022d), XdB(0x00354222), XdB(0x0038b828), XdB(0x003c67c2), + XdB(0x004054ae), XdB(0x004482e8), XdB(0x0048f6af), XdB(0x004db488), + XdB(0x0052c142), XdB(0x005821ff), XdB(0x005ddc33), XdB(0x0063f5b0), + XdB(0x006a74a7), XdB(0x00715faf), XdB(0x0078bdce), XdB(0x0080967f), + XdB(0x0088f1ba), XdB(0x0091d7f9), XdB(0x009b5247), XdB(0x00a56a41), + XdB(0x00b02a27), XdB(0x00bb9ce2), XdB(0x00c7ce12), XdB(0x00d4ca17), + XdB(0x00e29e20), XdB(0x00f15835), XdB(0x0101074b), XdB(0x0111bb4e), + XdB(0x01238531), XdB(0x01367704), XdB(0x014aa402), XdB(0x016020a7), + XdB(0x017702c3), XdB(0x018f6190), XdB(0x01a955cb), XdB(0x01c4f9cf), + XdB(0x01e269a8), XdB(0x0201c33b), XdB(0x0223265a), XdB(0x0246b4ea), + XdB(0x026c9302), XdB(0x0294e716), XdB(0x02bfda13), XdB(0x02ed9793), + XdB(0x031e4e09), XdB(0x03522ee4), XdB(0x03896ed0), XdB(0x03c445e2), + XdB(0x0402efd6), XdB(0x0445ac4b), XdB(0x048cbefc), XdB(0x04d87013), + XdB(0x05290c67), XdB(0x057ee5ca), XdB(0x05da5364), XdB(0x063bb204), + XdB(0x06a36485), XdB(0x0711d42b), XdB(0x0787710e), XdB(0x0804b299), + XdB(0x088a17ef), XdB(0x0918287e), XdB(0x09af747c), XdB(0x0a50957e), + XdB(0x0afc2f19), XdB(0x0bb2ef7f), XdB(0x0c759034), XdB(0x0d44d6ca), + XdB(0x0e2195bc), XdB(0x0f0cad0d), XdB(0x10070b62), XdB(0x1111aeea), + XdB(0x122da66c), XdB(0x135c120f), XdB(0x149e24d9), XdB(0x15f525b1), + XdB(0x176270e3), XdB(0x18e7794b), XdB(0x1a85c9ae), XdB(0x1c3f06d1), + XdB(0x1e14f07d), XdB(0x200963d7), XdB(0x221e5ccd), XdB(0x2455f870), + XdB(0x26b2770b), XdB(0x29363e2b), XdB(0x2be3db5c), XdB(0x2ebe06b6), + XdB(0x31c7a55b), XdB(0x3503ccd4), XdB(0x3875c5aa), XdB(0x3c210f44), + XdB(0x4009632b), XdB(0x4432b8cf), XdB(0x48a149bc), XdB(0x4d59959e), + XdB(0x52606733), XdB(0x57bad899), XdB(0x5d6e593a), XdB(0x6380b298), + XdB(0x69f80e9a), XdB(0x70dafda8), XdB(0x78307d76), XdB(0x7fffffff), +}; + +static void render_line(int n, int x0,int x1,int y0,int y1,ogg_int32_t *d){ + int dy=y1-y0; + int adx=x1-x0; + int ady=abs(dy); + int base=dy/adx; + int sy=(dy<0?base-1:base+1); + int x=x0; + int y=y0; + int err=0; + + if(n>x1)n=x1; + ady-=abs(base*adx); + + if(x=adx){ + err-=adx; + y+=sy; + }else{ + y+=base; + } + d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]); + } +} + +static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){ + vorbis_look_floor1 *look=(vorbis_look_floor1 *)in; + vorbis_info_floor1 *info=look->vi; + codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup; + + int i,j,k; + codebook *books=ci->fullbooks; + + /* unpack wrapped/predicted values from stream */ + if(oggpack_read(&vb->opb,1)==1){ + int *fit_value=(int *)_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value)); + + fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); + fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); + + /* partition by partition */ + /* partition by partition */ + for(i=0,j=2;ipartitions;i++){ + int classv=info->partitionclass[i]; + int cdim=info->class_dim[classv]; + int csubbits=info->class_subs[classv]; + int csub=1<class_book[classv],&vb->opb); + + if(cval==-1)goto eop; + } + + for(k=0;kclass_subbook[classv][cval&(csub-1)]; + cval>>=csubbits; + if(book>=0){ + if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1) + goto eop; + }else{ + fit_value[j+k]=0; + } + } + j+=cdim; + } + + /* unwrap positive values and reconsitute via linear interpolation */ + for(i=2;iposts;i++){ + int predicted=render_point(info->postlist[look->loneighbor[i-2]], + info->postlist[look->hineighbor[i-2]], + fit_value[look->loneighbor[i-2]], + fit_value[look->hineighbor[i-2]], + info->postlist[i]); + int hiroom=look->quant_q-predicted; + int loroom=predicted; + int room=(hiroom=room){ + if(hiroom>loroom){ + val = val-loroom; + }else{ + val = -1-(val-hiroom); + } + }else{ + if(val&1){ + val= -((val+1)>>1); + }else{ + val>>=1; + } + } + + fit_value[i]=val+predicted; + fit_value[look->loneighbor[i-2]]&=0x7fff; + fit_value[look->hineighbor[i-2]]&=0x7fff; + + }else{ + fit_value[i]=predicted|0x8000; + } + + } + + return(fit_value); + } + eop: + return(NULL); +} + +static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo, + ogg_int32_t *out){ + vorbis_look_floor1 *look=(vorbis_look_floor1 *)in; + vorbis_info_floor1 *info=look->vi; + + codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup; + int n=ci->blocksizes[vb->W]/2; + int j; + + if(memo){ + /* render the lines */ + int *fit_value=(int *)memo; + int hx=0; + int lx=0; + int ly=fit_value[0]*info->mult; + for(j=1;jposts;j++){ + int current=look->forward_index[j]; + int hy=fit_value[current]&0x7fff; + if(hy==fit_value[current]){ + + hy*=info->mult; + hx=info->postlist[current]; + + render_line(n,lx,hx,ly,hy,out); + + lx=hx; + ly=hy; + } + } + for(j=hx;j +#include +#include "ogg.h" +#include "misc.h" + + +/* A complete description of Ogg framing exists in docs/framing.html */ + +/* basic, centralized Ogg memory management based on linked lists of + references to refcounted memory buffers. References and buffers + are both recycled. Buffers are passed around and consumed in + reference form. */ + +static ogg_buffer_state *ogg_buffer_create(void){ + ogg_buffer_state *bs=_ogg_calloc(1,sizeof(*bs)); + return bs; +} + +/* destruction is 'lazy'; there may be memory references outstanding, + and yanking the buffer state out from underneath would be + antisocial. Dealloc what is currently unused and have + _release_one watch for the stragglers to come in. When they do, + finish destruction. */ + +/* call the helper while holding lock */ +static void _ogg_buffer_destroy(ogg_buffer_state *bs){ + ogg_buffer *bt; + ogg_reference *rt; + + if(bs->shutdown){ + + bt=bs->unused_buffers; + rt=bs->unused_references; + + while(bt){ + ogg_buffer *b=bt; + bt=b->ptr.next; + if(b->data)_ogg_free(b->data); + _ogg_free(b); + } + bs->unused_buffers=0; + while(rt){ + ogg_reference *r=rt; + rt=r->next; + _ogg_free(r); + } + bs->unused_references=0; + + if(!bs->outstanding) + _ogg_free(bs); + + } +} + +static void ogg_buffer_destroy(ogg_buffer_state *bs){ + bs->shutdown=1; + _ogg_buffer_destroy(bs); +} + +static ogg_buffer *_fetch_buffer(ogg_buffer_state *bs,long bytes){ + ogg_buffer *ob; + bs->outstanding++; + + /* do we have an unused buffer sitting in the pool? */ + if(bs->unused_buffers){ + ob=bs->unused_buffers; + bs->unused_buffers=ob->ptr.next; + + /* if the unused buffer is too small, grow it */ + if(ob->sizedata=_ogg_realloc(ob->data,bytes); + ob->size=bytes; + } + }else{ + /* allocate a new buffer */ + ob=_ogg_malloc(sizeof(*ob)); + ob->data=_ogg_malloc(bytes<16?16:bytes); + ob->size=bytes; + } + + ob->refcount=1; + ob->ptr.owner=bs; + return ob; +} + +static ogg_reference *_fetch_ref(ogg_buffer_state *bs){ + ogg_reference *or; + bs->outstanding++; + + /* do we have an unused reference sitting in the pool? */ + if(bs->unused_references){ + or=bs->unused_references; + bs->unused_references=or->next; + }else{ + /* allocate a new reference */ + or=_ogg_malloc(sizeof(*or)); + } + + or->begin=0; + or->length=0; + or->next=0; + return or; +} + +/* fetch a reference pointing to a fresh, initially continguous buffer + of at least [bytes] length */ +static ogg_reference *ogg_buffer_alloc(ogg_buffer_state *bs,long bytes){ + ogg_buffer *ob=_fetch_buffer(bs,bytes); + ogg_reference *or=_fetch_ref(bs); + or->buffer=ob; + return or; +} + +/* enlarge the data buffer in the current link */ +static void ogg_buffer_realloc(ogg_reference *or,long bytes){ + ogg_buffer *ob=or->buffer; + + /* if the unused buffer is too small, grow it */ + if(ob->sizedata=_ogg_realloc(ob->data,bytes); + ob->size=bytes; + } +} + +static void _ogg_buffer_mark_one(ogg_reference *or){ + or->buffer->refcount++; +} + +/* increase the refcount of the buffers to which the reference points */ +static void ogg_buffer_mark(ogg_reference *or){ + while(or){ + _ogg_buffer_mark_one(or); + or=or->next; + } +} + +/* duplicate a reference (pointing to the same actual buffer memory) + and increment buffer refcount. If the desired segment begins out + of range, NULL is returned; if the desired segment is simply zero + length, a zero length ref is returned. Partial range overlap + returns the overlap of the ranges */ +static ogg_reference *ogg_buffer_sub(ogg_reference *or,long begin,long length){ + ogg_reference *ret=0,*head=0; + + /* walk past any preceeding fragments we don't want */ + while(or && begin>=or->length){ + begin-=or->length; + or=or->next; + } + + /* duplicate the reference chain; increment refcounts */ + while(or && length){ + ogg_reference *temp=_fetch_ref(or->buffer->ptr.owner); + if(head) + head->next=temp; + else + ret=temp; + head=temp; + head->buffer=or->buffer; + head->begin=or->begin+begin; + head->length=length; + if(head->length>or->length-begin) + head->length=or->length-begin; + + begin=0; + length-=head->length; + or=or->next; + } + + ogg_buffer_mark(ret); + return ret; +} + +ogg_reference *ogg_buffer_dup(ogg_reference *or){ + ogg_reference *ret=0,*head=0; + /* duplicate the reference chain; increment refcounts */ + while(or){ + ogg_reference *temp=_fetch_ref(or->buffer->ptr.owner); + if(head) + head->next=temp; + else + ret=temp; + head=temp; + head->buffer=or->buffer; + head->begin=or->begin; + head->length=or->length; + or=or->next; + } + + ogg_buffer_mark(ret); + return ret; +} + +/* split a reference into two references; 'return' is a reference to + the buffer preceeding pos and 'head'/'tail' are the buffer past the + split. If pos is at or past the end of the passed in segment, + 'head/tail' are NULL */ +static ogg_reference *ogg_buffer_split(ogg_reference **tail, + ogg_reference **head,long pos){ + + /* walk past any preceeding fragments to one of: + a) the exact boundary that seps two fragments + b) the fragment that needs split somewhere in the middle */ + ogg_reference *ret=*tail; + ogg_reference *or=*tail; + + while(or && pos>or->length){ + pos-=or->length; + or=or->next; + } + + if(!or || pos==0){ + + return 0; + + }else{ + + if(pos>=or->length){ + /* exact split, or off the end? */ + if(or->next){ + + /* a split */ + *tail=or->next; + or->next=0; + + }else{ + + /* off or at the end */ + *tail=*head=0; + + } + }else{ + + /* split within a fragment */ + long lengthA=pos; + long beginB=or->begin+pos; + long lengthB=or->length-pos; + + /* make a new reference to tail the second piece */ + *tail=_fetch_ref(or->buffer->ptr.owner); + + (*tail)->buffer=or->buffer; + (*tail)->begin=beginB; + (*tail)->length=lengthB; + (*tail)->next=or->next; + _ogg_buffer_mark_one(*tail); + if(head && or==*head)*head=*tail; + + /* update the first piece */ + or->next=0; + or->length=lengthA; + + } + } + return ret; +} + +static void ogg_buffer_release_one(ogg_reference *or){ + ogg_buffer *ob=or->buffer; + ogg_buffer_state *bs=ob->ptr.owner; + + ob->refcount--; + if(ob->refcount==0){ + bs->outstanding--; /* for the returned buffer */ + ob->ptr.next=bs->unused_buffers; + bs->unused_buffers=ob; + } + + bs->outstanding--; /* for the returned reference */ + or->next=bs->unused_references; + bs->unused_references=or; + + _ogg_buffer_destroy(bs); /* lazy cleanup (if needed) */ + +} + +/* release the references, decrease the refcounts of buffers to which + they point, release any buffers with a refcount that drops to zero */ +static void ogg_buffer_release(ogg_reference *or){ + while(or){ + ogg_reference *next=or->next; + ogg_buffer_release_one(or); + or=next; + } +} + +static ogg_reference *ogg_buffer_pretruncate(ogg_reference *or,long pos){ + /* release preceeding fragments we don't want */ + while(or && pos>=or->length){ + ogg_reference *next=or->next; + pos-=or->length; + ogg_buffer_release_one(or); + or=next; + } + if (or) { + or->begin+=pos; + or->length-=pos; + } + return or; +} + +static ogg_reference *ogg_buffer_walk(ogg_reference *or){ + if(!or)return NULL; + while(or->next){ + or=or->next; + } + return(or); +} + +/* *head is appended to the front end (head) of *tail; both continue to + be valid pointers, with *tail at the tail and *head at the head */ +static ogg_reference *ogg_buffer_cat(ogg_reference *tail, ogg_reference *head){ + if(!tail)return head; + + while(tail->next){ + tail=tail->next; + } + tail->next=head; + return ogg_buffer_walk(head); +} + +static void _positionB(oggbyte_buffer *b,int pos){ + if(pospos){ + /* start at beginning, scan forward */ + b->ref=b->baseref; + b->pos=0; + b->end=b->pos+b->ref->length; + b->ptr=b->ref->buffer->data+b->ref->begin; + } +} + +static void _positionF(oggbyte_buffer *b,int pos){ + /* scan forward for position */ + while(pos>=b->end){ + /* just seek forward */ + b->pos+=b->ref->length; + b->ref=b->ref->next; + b->end=b->ref->length+b->pos; + b->ptr=b->ref->buffer->data+b->ref->begin; + } +} + +static int oggbyte_init(oggbyte_buffer *b,ogg_reference *or){ + memset(b,0,sizeof(*b)); + if(or){ + b->ref=b->baseref=or; + b->pos=0; + b->end=b->ref->length; + b->ptr=b->ref->buffer->data+b->ref->begin; + return 0; + }else + return -1; +} + +static void oggbyte_set4(oggbyte_buffer *b,ogg_uint32_t val,int pos){ + int i; + _positionB(b,pos); + for(i=0;i<4;i++){ + _positionF(b,pos); + b->ptr[pos-b->pos]=val; + val>>=8; + ++pos; + } +} + +static unsigned char oggbyte_read1(oggbyte_buffer *b,int pos){ + _positionB(b,pos); + _positionF(b,pos); + return b->ptr[pos-b->pos]; +} + +static ogg_uint32_t oggbyte_read4(oggbyte_buffer *b,int pos){ + ogg_uint32_t ret; + _positionB(b,pos); + _positionF(b,pos); + ret=b->ptr[pos-b->pos]; + _positionF(b,++pos); + ret|=b->ptr[pos-b->pos]<<8; + _positionF(b,++pos); + ret|=b->ptr[pos-b->pos]<<16; + _positionF(b,++pos); + ret|=b->ptr[pos-b->pos]<<24; + return ret; +} + +static ogg_int64_t oggbyte_read8(oggbyte_buffer *b,int pos){ + ogg_int64_t ret; + unsigned char t[7]; + int i; + _positionB(b,pos); + for(i=0;i<7;i++){ + _positionF(b,pos); + t[i]=b->ptr[pos++ -b->pos]; + } + + _positionF(b,pos); + ret=b->ptr[pos-b->pos]; + + for(i=6;i>=0;--i) + ret= ret<<8 | t[i]; + + return ret; +} + +/* Now we get to the actual framing code */ + +int ogg_page_version(ogg_page *og){ + oggbyte_buffer ob; + oggbyte_init(&ob,og->header); + return oggbyte_read1(&ob,4); +} + +int ogg_page_continued(ogg_page *og){ + oggbyte_buffer ob; + oggbyte_init(&ob,og->header); + return oggbyte_read1(&ob,5)&0x01; +} + +int ogg_page_bos(ogg_page *og){ + oggbyte_buffer ob; + oggbyte_init(&ob,og->header); + return oggbyte_read1(&ob,5)&0x02; +} + +int ogg_page_eos(ogg_page *og){ + oggbyte_buffer ob; + oggbyte_init(&ob,og->header); + return oggbyte_read1(&ob,5)&0x04; +} + +ogg_int64_t ogg_page_granulepos(ogg_page *og){ + oggbyte_buffer ob; + oggbyte_init(&ob,og->header); + return oggbyte_read8(&ob,6); +} + +ogg_uint32_t ogg_page_serialno(ogg_page *og){ + oggbyte_buffer ob; + oggbyte_init(&ob,og->header); + return oggbyte_read4(&ob,14); +} + +ogg_uint32_t ogg_page_pageno(ogg_page *og){ + oggbyte_buffer ob; + oggbyte_init(&ob,og->header); + return oggbyte_read4(&ob,18); +} + +/* returns the number of packets that are completed on this page (if + the leading packet is begun on a previous page, but ends on this + page, it's counted */ + +/* NOTE: +If a page consists of a packet begun on a previous page, and a new +packet begun (but not completed) on this page, the return will be: + ogg_page_packets(page) ==1, + ogg_page_continued(page) !=0 + +If a page happens to be a single packet that was begun on a +previous page, and spans to the next page (in the case of a three or +more page packet), the return will be: + ogg_page_packets(page) ==0, + ogg_page_continued(page) !=0 +*/ + +int ogg_page_packets(ogg_page *og){ + int i; + int n; + int count=0; + oggbyte_buffer ob; + oggbyte_init(&ob,og->header); + + n=oggbyte_read1(&ob,26); + for(i=0;ibufferpool=ogg_buffer_create(); + return oy; +} + +int ogg_sync_destroy(ogg_sync_state *oy){ + if(oy){ + ogg_sync_reset(oy); + ogg_buffer_destroy(oy->bufferpool); + memset(oy,0,sizeof(*oy)); + _ogg_free(oy); + } + return OGG_SUCCESS; +} + +unsigned char *ogg_sync_bufferin(ogg_sync_state *oy, long bytes){ + + /* [allocate and] expose a buffer for data submission. + + If there is no head fragment + allocate one and expose it + else + if the current head fragment has sufficient unused space + expose it + else + if the current head fragment is unused + resize and expose it + else + allocate new fragment and expose it + */ + + /* base case; fifo uninitialized */ + if(!oy->fifo_head){ + oy->fifo_head=oy->fifo_tail=ogg_buffer_alloc(oy->bufferpool,bytes); + return oy->fifo_head->buffer->data; + } + + /* space left in current fragment case */ + if(oy->fifo_head->buffer->size- + oy->fifo_head->length- + oy->fifo_head->begin >= bytes) + return oy->fifo_head->buffer->data+ + oy->fifo_head->length+oy->fifo_head->begin; + + /* current fragment is unused, but too small */ + if(!oy->fifo_head->length){ + ogg_buffer_realloc(oy->fifo_head,bytes); + return oy->fifo_head->buffer->data+oy->fifo_head->begin; + } + + /* current fragment used/full; get new fragment */ + { + ogg_reference *new=ogg_buffer_alloc(oy->bufferpool,bytes); + oy->fifo_head->next=new; + oy->fifo_head=new; + } + return oy->fifo_head->buffer->data; +} + +int ogg_sync_wrote(ogg_sync_state *oy, long bytes){ + if(!oy->fifo_head)return OGG_EINVAL; + if(oy->fifo_head->buffer->size-oy->fifo_head->length-oy->fifo_head->begin < + bytes)return OGG_EINVAL; + oy->fifo_head->length+=bytes; + oy->fifo_fill+=bytes; + return OGG_SUCCESS; +} + +static ogg_uint32_t _checksum(ogg_reference *or, int bytes){ + ogg_uint32_t crc_reg=0; + int j,post; + + while(or){ + unsigned char *data=or->buffer->data+or->begin; + post=(byteslength?bytes:or->length); + for(j=0;j> 24)&0xff)^data[j]]; + bytes-=j; + or=or->next; + } + + return crc_reg; +} + + +/* sync the stream. This is meant to be useful for finding page + boundaries. + + return values for this: + -n) skipped n bytes + 0) page not ready; more data (no bytes skipped) + n) page synced at current location; page length n bytes + +*/ + +long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){ + oggbyte_buffer page; + long bytes,ret=0; + + ogg_page_release(og); + + bytes=oy->fifo_fill; + oggbyte_init(&page,oy->fifo_tail); + + if(oy->headerbytes==0){ + if(bytes<27)goto sync_out; /* not enough for even a minimal header */ + + /* verify capture pattern */ + if(oggbyte_read1(&page,0)!=(int)'O' || + oggbyte_read1(&page,1)!=(int)'g' || + oggbyte_read1(&page,2)!=(int)'g' || + oggbyte_read1(&page,3)!=(int)'S' ) goto sync_fail; + + oy->headerbytes=oggbyte_read1(&page,26)+27; + } + if(bytesheaderbytes)goto sync_out; /* not enough for header + + seg table */ + if(oy->bodybytes==0){ + int i; + /* count up body length in the segment table */ + for(i=0;iheaderbytes-27;i++) + oy->bodybytes+=oggbyte_read1(&page,27+i); + } + + if(oy->bodybytes+oy->headerbytes>bytes)goto sync_out; + + /* we have what appears to be a complete page; last test: verify + checksum */ + { + ogg_uint32_t chksum=oggbyte_read4(&page,22); + oggbyte_set4(&page,0,22); + + /* Compare checksums; memory continues to be common access */ + if(chksum!=_checksum(oy->fifo_tail,oy->bodybytes+oy->headerbytes)){ + + /* D'oh. Mismatch! Corrupt page (or miscapture and not a page + at all). replace the computed checksum with the one actually + read in; remember all the memory is common access */ + + oggbyte_set4(&page,chksum,22); + goto sync_fail; + } + oggbyte_set4(&page,chksum,22); + } + + /* We have a page. Set up page return. */ + if(og){ + /* set up page output */ + og->header=ogg_buffer_split(&oy->fifo_tail,&oy->fifo_head,oy->headerbytes); + og->header_len=oy->headerbytes; + og->body=ogg_buffer_split(&oy->fifo_tail,&oy->fifo_head,oy->bodybytes); + og->body_len=oy->bodybytes; + }else{ + /* simply advance */ + oy->fifo_tail= + ogg_buffer_pretruncate(oy->fifo_tail,oy->headerbytes+oy->bodybytes); + if(!oy->fifo_tail)oy->fifo_head=0; + } + + ret=oy->headerbytes+oy->bodybytes; + oy->unsynced=0; + oy->headerbytes=0; + oy->bodybytes=0; + oy->fifo_fill-=ret; + + return ret; + + sync_fail: + + oy->headerbytes=0; + oy->bodybytes=0; + oy->fifo_tail=ogg_buffer_pretruncate(oy->fifo_tail,1); + ret--; + + /* search forward through fragments for possible capture */ + while(oy->fifo_tail){ + /* invariant: fifo_cursor points to a position in fifo_tail */ + unsigned char *now=oy->fifo_tail->buffer->data+oy->fifo_tail->begin; + unsigned char *next=memchr(now, 'O', oy->fifo_tail->length); + + if(next){ + /* possible capture in this segment */ + long bytes=next-now; + oy->fifo_tail=ogg_buffer_pretruncate(oy->fifo_tail,bytes); + ret-=bytes; + break; + }else{ + /* no capture. advance to next segment */ + long bytes=oy->fifo_tail->length; + ret-=bytes; + oy->fifo_tail=ogg_buffer_pretruncate(oy->fifo_tail,bytes); + } + } + if(!oy->fifo_tail)oy->fifo_head=0; + oy->fifo_fill+=ret; + + sync_out: + return ret; +} + +/* sync the stream and get a page. Keep trying until we find a page. + Supress 'sync errors' after reporting the first. + + return values: + OGG_HOLE) recapture (hole in data) + 0) need more data + 1) page returned + + Returns pointers into buffered data; invalidated by next call to + _stream, _clear, _init, or _buffer */ + +int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){ + + /* all we need to do is verify a page at the head of the stream + buffer. If it doesn't verify, we look for the next potential + frame */ + + while(1){ + long ret=ogg_sync_pageseek(oy,og); + if(ret>0){ + /* have a page */ + return 1; + } + if(ret==0){ + /* need more data */ + return 0; + } + + /* head did not start a synced page... skipped some bytes */ + if(!oy->unsynced){ + oy->unsynced=1; + return OGG_HOLE; + } + + /* loop. keep looking */ + + } +} + +/* clear things to an initial state. Good to call, eg, before seeking */ +int ogg_sync_reset(ogg_sync_state *oy){ + + ogg_buffer_release(oy->fifo_tail); + oy->fifo_tail=0; + oy->fifo_head=0; + oy->fifo_fill=0; + + oy->unsynced=0; + oy->headerbytes=0; + oy->bodybytes=0; + return OGG_SUCCESS; +} + +ogg_stream_state *ogg_stream_create(int serialno){ + ogg_stream_state *os=_ogg_calloc(1,sizeof(*os)); + os->serialno=serialno; + os->pageno=-1; + return os; +} + +int ogg_stream_destroy(ogg_stream_state *os){ + if(os){ + ogg_buffer_release(os->header_tail); + ogg_buffer_release(os->body_tail); + memset(os,0,sizeof(*os)); + _ogg_free(os); + } + return OGG_SUCCESS; +} + + +#define FINFLAG 0x80000000UL +#define FINMASK 0x7fffffffUL + +static void _next_lace(oggbyte_buffer *ob,ogg_stream_state *os){ + /* search ahead one lace */ + os->body_fill_next=0; + while(os->laceptrlacing_fill){ + int val=oggbyte_read1(ob,27+os->laceptr++); + os->body_fill_next+=val; + if(val<255){ + os->body_fill_next|=FINFLAG; + os->clearflag=1; + break; + } + } +} + +static void _span_queued_page(ogg_stream_state *os){ + while( !(os->body_fill&FINFLAG) ){ + + if(!os->header_tail)break; + + /* first flush out preceeding page header (if any). Body is + flushed as it's consumed, so that's not done here. */ + + if(os->lacing_fill>=0) + os->header_tail=ogg_buffer_pretruncate(os->header_tail, + os->lacing_fill+27); + os->lacing_fill=0; + os->laceptr=0; + os->clearflag=0; + + if(!os->header_tail){ + os->header_head=0; + break; + }else{ + + /* process/prepare next page, if any */ + + long pageno; + oggbyte_buffer ob; + ogg_page og; /* only for parsing header values */ + og.header=os->header_tail; /* only for parsing header values */ + pageno=ogg_page_pageno(&og); + + oggbyte_init(&ob,os->header_tail); + os->lacing_fill=oggbyte_read1(&ob,26); + + /* are we in sequence? */ + if(pageno!=os->pageno){ + if(os->pageno==-1) /* indicates seek or reset */ + os->holeflag=1; /* set for internal use */ + else + os->holeflag=2; /* set for external reporting */ + + os->body_tail=ogg_buffer_pretruncate(os->body_tail, + os->body_fill); + if(os->body_tail==0)os->body_head=0; + os->body_fill=0; + + } + + if(ogg_page_continued(&og)){ + if(os->body_fill==0){ + /* continued packet, but no preceeding data to continue */ + /* dump the first partial packet on the page */ + _next_lace(&ob,os); + os->body_tail= + ogg_buffer_pretruncate(os->body_tail,os->body_fill_next&FINMASK); + if(os->body_tail==0)os->body_head=0; + /* set span flag */ + if(!os->spanflag && !os->holeflag)os->spanflag=2; + } + }else{ + if(os->body_fill>0){ + /* preceeding data to continue, but not a continued page */ + /* dump body_fill */ + os->body_tail=ogg_buffer_pretruncate(os->body_tail, + os->body_fill); + if(os->body_tail==0)os->body_head=0; + os->body_fill=0; + + /* set espan flag */ + if(!os->spanflag && !os->holeflag)os->spanflag=2; + } + } + + if(os->laceptrlacing_fill){ + os->granulepos=ogg_page_granulepos(&og); + + /* get current packet size & flag */ + _next_lace(&ob,os); + os->body_fill+=os->body_fill_next; /* addition handles the flag fine; + unsigned on purpose */ + /* ...and next packet size & flag */ + _next_lace(&ob,os); + + } + + os->pageno=pageno+1; + os->e_o_s=ogg_page_eos(&og); + os->b_o_s=ogg_page_bos(&og); + + } + } +} + +/* add the incoming page to the stream state; we decompose the page + into packet segments here as well. */ + +int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){ + + int serialno=ogg_page_serialno(og); + int version=ogg_page_version(og); + + /* check the serial number */ + if(serialno!=os->serialno){ + ogg_page_release(og); + return OGG_ESERIAL; + } + if(version>0){ + ogg_page_release(og); + return OGG_EVERSION; + } + + /* add to fifos */ + if(!os->body_tail){ + os->body_tail=og->body; + os->body_head=ogg_buffer_walk(og->body); + }else{ + os->body_head=ogg_buffer_cat(os->body_head,og->body); + } + if(!os->header_tail){ + os->header_tail=og->header; + os->header_head=ogg_buffer_walk(og->header); + os->lacing_fill=-27; + }else{ + os->header_head=ogg_buffer_cat(os->header_head,og->header); + } + + memset(og,0,sizeof(*og)); + return OGG_SUCCESS; +} + +int ogg_stream_reset(ogg_stream_state *os){ + + ogg_buffer_release(os->header_tail); + ogg_buffer_release(os->body_tail); + os->header_tail=os->header_head=0; + os->body_tail=os->body_head=0; + + os->e_o_s=0; + os->b_o_s=0; + os->pageno=-1; + os->packetno=0; + os->granulepos=0; + + os->body_fill=0; + os->lacing_fill=0; + + os->holeflag=0; + os->spanflag=0; + os->clearflag=0; + os->laceptr=0; + os->body_fill_next=0; + + return OGG_SUCCESS; +} + +int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){ + ogg_stream_reset(os); + os->serialno=serialno; + return OGG_SUCCESS; +} + +static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){ + + ogg_packet_release(op); + _span_queued_page(os); + + if(os->holeflag){ + int temp=os->holeflag; + if(os->clearflag) + os->holeflag=0; + else + os->holeflag=1; + if(temp==2){ + os->packetno++; + return OGG_HOLE; + } + } + if(os->spanflag){ + int temp=os->spanflag; + if(os->clearflag) + os->spanflag=0; + else + os->spanflag=1; + if(temp==2){ + os->packetno++; + return OGG_SPAN; + } + } + + if(!(os->body_fill&FINFLAG)) return 0; + if(!op && !adv)return 1; /* just using peek as an inexpensive way + to ask if there's a whole packet + waiting */ + if(op){ + op->b_o_s=os->b_o_s; + if(os->e_o_s && os->body_fill_next==0) + op->e_o_s=os->e_o_s; + else + op->e_o_s=0; + if( (os->body_fill&FINFLAG) && !(os->body_fill_next&FINFLAG) ) + op->granulepos=os->granulepos; + else + op->granulepos=-1; + op->packetno=os->packetno; + } + + if(adv){ + oggbyte_buffer ob; + oggbyte_init(&ob,os->header_tail); + + /* split the body contents off */ + if(op){ + op->packet=ogg_buffer_split(&os->body_tail,&os->body_head, + os->body_fill&FINMASK); + op->bytes=os->body_fill&FINMASK; + }else{ + os->body_tail=ogg_buffer_pretruncate(os->body_tail, + os->body_fill&FINMASK); + if(os->body_tail==0)os->body_head=0; + } + + /* update lacing pointers */ + os->body_fill=os->body_fill_next; + _next_lace(&ob,os); + }else{ + if(op){ + op->packet=ogg_buffer_sub(os->body_tail,0,os->body_fill&FINMASK); + op->bytes=os->body_fill&FINMASK; + } + } + + if(adv){ + os->packetno++; + os->b_o_s=0; + } + + return 1; +} + +int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){ + return _packetout(os,op,1); +} + +int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){ + return _packetout(os,op,0); +} + +int ogg_packet_release(ogg_packet *op) { + if(op){ + ogg_buffer_release(op->packet); + memset(op, 0, sizeof(*op)); + } + return OGG_SUCCESS; +} + +int ogg_page_release(ogg_page *og) { + if(og){ + ogg_buffer_release(og->header); + ogg_buffer_release(og->body); + memset(og, 0, sizeof(*og)); + } + return OGG_SUCCESS; +} + +void ogg_page_dup(ogg_page *dup,ogg_page *orig){ + dup->header_len=orig->header_len; + dup->body_len=orig->body_len; + dup->header=ogg_buffer_dup(orig->header); + dup->body=ogg_buffer_dup(orig->body); +} + diff --git a/genplus-gx/core/tremor/info.c b/genplus-gx/core/tremor/info.c new file mode 100644 index 0000000000..200e5f95f9 --- /dev/null +++ b/genplus-gx/core/tremor/info.c @@ -0,0 +1,356 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: maintain the info structure, info <-> header packets + + ********************************************************************/ + +/* general handling of the header and the vorbis_info structure (and + substructures) */ + +#include +#include +#include +#include "ogg.h" +#include "ivorbiscodec.h" +#include "codec_internal.h" +#include "codebook.h" +#include "registry.h" +#include "window.h" +#include "misc.h" + +/* helpers */ +static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ + while(bytes--){ + *buf++=oggpack_read(o,8); + } +} + +void vorbis_comment_init(vorbis_comment *vc){ + memset(vc,0,sizeof(*vc)); +} + +/* This is more or less the same as strncasecmp - but that doesn't exist + * everywhere, and this is a fairly trivial function, so we include it */ +static int tagcompare(const char *s1, const char *s2, int n){ + int c=0; + while(c < n){ + if(toupper((int)s1[c]) != toupper((int)s2[c])) + return !0; + c++; + } + return 0; +} + +char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){ + long i; + int found = 0; + int taglen = strlen(tag)+1; /* +1 for the = we append */ + char *fulltag = (char *)alloca(taglen+ 1); + + strcpy(fulltag, tag); + strcat(fulltag, "="); + + for(i=0;icomments;i++){ + if(!tagcompare(vc->user_comments[i], fulltag, taglen)){ + if(count == found) + /* We return a pointer to the data, not a copy */ + return vc->user_comments[i] + taglen; + else + found++; + } + } + return NULL; /* didn't find anything */ +} + +int vorbis_comment_query_count(vorbis_comment *vc, char *tag){ + int i,count=0; + int taglen = strlen(tag)+1; /* +1 for the = we append */ + char *fulltag = (char *)alloca(taglen+1); + strcpy(fulltag,tag); + strcat(fulltag, "="); + + for(i=0;icomments;i++){ + if(!tagcompare(vc->user_comments[i], fulltag, taglen)) + count++; + } + + return count; +} + +void vorbis_comment_clear(vorbis_comment *vc){ + if(vc){ + long i; + for(i=0;icomments;i++) + if(vc->user_comments[i])_ogg_free(vc->user_comments[i]); + if(vc->user_comments)_ogg_free(vc->user_comments); + if(vc->comment_lengths)_ogg_free(vc->comment_lengths); + if(vc->vendor)_ogg_free(vc->vendor); + memset(vc,0,sizeof(*vc)); + } +} + +/* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. + They may be equal, but short will never ge greater than long */ +int vorbis_info_blocksize(vorbis_info *vi,int zo){ + codec_setup_info *ci = (codec_setup_info *)vi->codec_setup; + return ci ? ci->blocksizes[zo] : -1; +} + +/* used by synthesis, which has a full, alloced vi */ +void vorbis_info_init(vorbis_info *vi){ + memset(vi,0,sizeof(*vi)); + vi->codec_setup=(codec_setup_info *)_ogg_calloc(1,sizeof(codec_setup_info)); +} + +void vorbis_info_clear(vorbis_info *vi){ + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + int i; + + if(ci){ + + for(i=0;imodes;i++) + if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); + + for(i=0;imaps;i++) /* unpack does the range checking */ + if(ci->map_param[i]) + _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); + + for(i=0;ifloors;i++) /* unpack does the range checking */ + if(ci->floor_param[i]) + _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); + + for(i=0;iresidues;i++) /* unpack does the range checking */ + if(ci->residue_param[i]) + _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); + + for(i=0;ibooks;i++){ + if(ci->book_param[i]){ + /* knows if the book was not alloced */ + vorbis_staticbook_destroy(ci->book_param[i]); + } + if(ci->fullbooks) + vorbis_book_clear(ci->fullbooks+i); + } + if(ci->fullbooks) + _ogg_free(ci->fullbooks); + + _ogg_free(ci); + } + + memset(vi,0,sizeof(*vi)); +} + +/* Header packing/unpacking ********************************************/ + +static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + if(!ci)return(OV_EFAULT); + + vi->version=oggpack_read(opb,32); + if(vi->version!=0)return(OV_EVERSION); + + vi->channels=oggpack_read(opb,8); + vi->rate=oggpack_read(opb,32); + + vi->bitrate_upper=oggpack_read(opb,32); + vi->bitrate_nominal=oggpack_read(opb,32); + vi->bitrate_lower=oggpack_read(opb,32); + + ci->blocksizes[0]=1<blocksizes[1]=1<rate<1)goto err_out; + if(vi->channels<1)goto err_out; + if(ci->blocksizes[0]<64)goto err_out; + if(ci->blocksizes[1]blocksizes[0])goto err_out; + if(ci->blocksizes[1]>8192)goto err_out; + + if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ + + return(0); + err_out: + vorbis_info_clear(vi); + return(OV_EBADHEADER); +} + +static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ + int i; + int vendorlen=oggpack_read(opb,32); + if(vendorlen<0)goto err_out; + vc->vendor=(char *)_ogg_calloc(vendorlen+1,1); + _v_readstring(opb,vc->vendor,vendorlen); + vc->comments=oggpack_read(opb,32); + if(vc->comments<0)goto err_out; + vc->user_comments=(char **)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments)); + vc->comment_lengths=(int *)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths)); + + for(i=0;icomments;i++){ + int len=oggpack_read(opb,32); + if(len<0)goto err_out; + vc->comment_lengths[i]=len; + vc->user_comments[i]=(char *)_ogg_calloc(len+1,1); + _v_readstring(opb,vc->user_comments[i],len); + } + if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ + + return(0); + err_out: + vorbis_comment_clear(vc); + return(OV_EBADHEADER); +} + +/* all of the real encoding details are here. The modes, books, + everything */ +static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + int i; + if(!ci)return(OV_EFAULT); + + /* codebooks */ + ci->books=oggpack_read(opb,8)+1; + /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/ + for(i=0;ibooks;i++){ + ci->book_param[i]=(static_codebook *)_ogg_calloc(1,sizeof(*ci->book_param[i])); + if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out; + } + + /* time backend settings */ + ci->times=oggpack_read(opb,6)+1; + /*ci->time_type=_ogg_malloc(ci->times*sizeof(*ci->time_type));*/ + /*ci->time_param=_ogg_calloc(ci->times,sizeof(void *));*/ + for(i=0;itimes;i++){ + ci->time_type[i]=oggpack_read(opb,16); + if(ci->time_type[i]<0 || ci->time_type[i]>=VI_TIMEB)goto err_out; + /* ci->time_param[i]=_time_P[ci->time_type[i]]->unpack(vi,opb); + Vorbis I has no time backend */ + /*if(!ci->time_param[i])goto err_out;*/ + } + + /* floor backend settings */ + ci->floors=oggpack_read(opb,6)+1; + /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/ + /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/ + for(i=0;ifloors;i++){ + ci->floor_type[i]=oggpack_read(opb,16); + if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out; + ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb); + if(!ci->floor_param[i])goto err_out; + } + + /* residue backend settings */ + ci->residues=oggpack_read(opb,6)+1; + /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/ + /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/ + for(i=0;iresidues;i++){ + ci->residue_type[i]=oggpack_read(opb,16); + if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out; + ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb); + if(!ci->residue_param[i])goto err_out; + } + + /* map backend settings */ + ci->maps=oggpack_read(opb,6)+1; + /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/ + /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/ + for(i=0;imaps;i++){ + ci->map_type[i]=oggpack_read(opb,16); + if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out; + ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb); + if(!ci->map_param[i])goto err_out; + } + + /* mode settings */ + ci->modes=oggpack_read(opb,6)+1; + /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/ + for(i=0;imodes;i++){ + ci->mode_param[i]=(vorbis_info_mode *)_ogg_calloc(1,sizeof(*ci->mode_param[i])); + ci->mode_param[i]->blockflag=oggpack_read(opb,1); + ci->mode_param[i]->windowtype=oggpack_read(opb,16); + ci->mode_param[i]->transformtype=oggpack_read(opb,16); + ci->mode_param[i]->mapping=oggpack_read(opb,8); + + if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out; + if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out; + if(ci->mode_param[i]->mapping>=ci->maps)goto err_out; + } + + if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ + + return(0); + err_out: + vorbis_info_clear(vi); + return(OV_EBADHEADER); +} + +/* The Vorbis header is in three packets; the initial small packet in + the first page that identifies basic parameters, a second packet + with bitstream comments and a third packet that holds the + codebook. */ + +int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ + oggpack_buffer opb; + + if(op){ + oggpack_readinit(&opb,op->packet); + + /* Which of the three types of header is this? */ + /* Also verify header-ness, vorbis */ + { + char buffer[6]; + int packtype=oggpack_read(&opb,8); + memset(buffer,0,6); + _v_readstring(&opb,buffer,6); + if(memcmp(buffer,"vorbis",6)){ + /* not a vorbis header */ + return(OV_ENOTVORBIS); + } + switch(packtype){ + case 0x01: /* least significant *bit* is read first */ + if(!op->b_o_s){ + /* Not the initial packet */ + return(OV_EBADHEADER); + } + if(vi->rate!=0){ + /* previously initialized info header */ + return(OV_EBADHEADER); + } + + return(_vorbis_unpack_info(vi,&opb)); + + case 0x03: /* least significant *bit* is read first */ + if(vi->rate==0){ + /* um... we didn't get the initial header */ + return(OV_EBADHEADER); + } + + return(_vorbis_unpack_comment(vc,&opb)); + + case 0x05: /* least significant *bit* is read first */ + if(vi->rate==0 || vc->vendor==NULL){ + /* um... we didn;t get the initial header or comments yet */ + return(OV_EBADHEADER); + } + + return(_vorbis_unpack_books(vi,&opb)); + + default: + /* Not a valid vorbis header type */ + return(OV_EBADHEADER); + break; + } + } + } + return(OV_EBADHEADER); +} + diff --git a/genplus-gx/core/tremor/ivorbiscodec.h b/genplus-gx/core/tremor/ivorbiscodec.h new file mode 100644 index 0000000000..d4de1fd344 --- /dev/null +++ b/genplus-gx/core/tremor/ivorbiscodec.h @@ -0,0 +1,202 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: libvorbis codec headers + + ********************************************************************/ + +#ifndef _vorbis_codec_h_ +#define _vorbis_codec_h_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "ogg.h" + +typedef struct vorbis_info{ + int version; + int channels; + long rate; + + /* The below bitrate declarations are *hints*. + Combinations of the three values carry the following implications: + + all three set to the same value: + implies a fixed rate bitstream + only nominal set: + implies a VBR stream that averages the nominal bitrate. No hard + upper/lower limit + upper and or lower set: + implies a VBR bitstream that obeys the bitrate limits. nominal + may also be set to give a nominal rate. + none set: + the coder does not care to speculate. + */ + + long bitrate_upper; + long bitrate_nominal; + long bitrate_lower; + long bitrate_window; + + void *codec_setup; +} vorbis_info; + +/* vorbis_dsp_state buffers the current vorbis audio + analysis/synthesis state. The DSP state belongs to a specific + logical bitstream ****************************************************/ +typedef struct vorbis_dsp_state{ + int analysisp; + vorbis_info *vi; + + ogg_int32_t **pcm; + ogg_int32_t **pcmret; + int pcm_storage; + int pcm_current; + int pcm_returned; + + int preextrapolate; + int eofflag; + + long lW; + long W; + long nW; + long centerW; + + ogg_int64_t granulepos; + ogg_int64_t sequence; + + void *backend_state; +} vorbis_dsp_state; + +typedef struct vorbis_block{ + /* necessary stream state for linking to the framing abstraction */ + ogg_int32_t **pcm; /* this is a pointer into local storage */ + oggpack_buffer opb; + + long lW; + long W; + long nW; + int pcmend; + int mode; + + int eofflag; + ogg_int64_t granulepos; + ogg_int64_t sequence; + vorbis_dsp_state *vd; /* For read-only access of configuration */ + + /* local storage to avoid remallocing; it's up to the mapping to + structure it */ + void *localstore; + long localtop; + long localalloc; + long totaluse; + struct alloc_chain *reap; + +} vorbis_block; + +/* vorbis_block is a single block of data to be processed as part of +the analysis/synthesis stream; it belongs to a specific logical +bitstream, but is independant from other vorbis_blocks belonging to +that logical bitstream. *************************************************/ + +struct alloc_chain{ + void *ptr; + struct alloc_chain *next; +}; + +/* vorbis_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). vorbis_info and substructures are in backends.h. +*********************************************************************/ + +/* the comments are not part of vorbis_info so that vorbis_info can be + static storage */ +typedef struct vorbis_comment{ + /* unlimited user comment fields. libvorbis writes 'libvorbis' + whatever vendor is set to in encode */ + char **user_comments; + int *comment_lengths; + int comments; + char *vendor; + +} vorbis_comment; + + +/* libvorbis encodes in two abstraction layers; first we perform DSP + and produce a packet (see docs/analysis.txt). The packet is then + coded into a framed OggSquish bitstream by the second layer (see + docs/framing.txt). Decode is the reverse process; we sync/frame + the bitstream and extract individual packets, then decode the + packet back into PCM audio. + + The extra framing/packetizing is used in streaming formats, such as + files. Over the net (such as with UDP), the framing and + packetization aren't necessary as they're provided by the transport + and the streaming layer is not used */ + +/* Vorbis PRIMITIVES: general ***************************************/ + +extern void vorbis_info_init(vorbis_info *vi); +extern void vorbis_info_clear(vorbis_info *vi); +extern int vorbis_info_blocksize(vorbis_info *vi,int zo); +extern void vorbis_comment_init(vorbis_comment *vc); +extern void vorbis_comment_add(vorbis_comment *vc, char *comment); +extern void vorbis_comment_add_tag(vorbis_comment *vc, + char *tag, char *contents); +extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count); +extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag); +extern void vorbis_comment_clear(vorbis_comment *vc); + +extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); +extern int vorbis_block_clear(vorbis_block *vb); +extern void vorbis_dsp_clear(vorbis_dsp_state *v); + +/* Vorbis PRIMITIVES: synthesis layer *******************************/ +extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, + ogg_packet *op); + +extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_synthesis_restart(vorbis_dsp_state *v); +extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep); +extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,ogg_int32_t ***pcm); +extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); +extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); + +/* Vorbis ERRORS and return codes ***********************************/ + +#define OV_FALSE -1 +#define OV_EOF -2 +#define OV_HOLE -3 + +#define OV_EREAD -128 +#define OV_EFAULT -129 +#define OV_EIMPL -130 +#define OV_EINVAL -131 +#define OV_ENOTVORBIS -132 +#define OV_EBADHEADER -133 +#define OV_EVERSION -134 +#define OV_ENOTAUDIO -135 +#define OV_EBADPACKET -136 +#define OV_EBADLINK -137 +#define OV_ENOSEEK -138 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/genplus-gx/core/tremor/ivorbisfile.h b/genplus-gx/core/tremor/ivorbisfile.h new file mode 100644 index 0000000000..dd773788a1 --- /dev/null +++ b/genplus-gx/core/tremor/ivorbisfile.h @@ -0,0 +1,130 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + + ********************************************************************/ + +#ifndef _OV_FILE_H_ +#define _OV_FILE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include +#include "ivorbiscodec.h" + +#define CHUNKSIZE 1024 +/* The function prototypes for the callbacks are basically the same as for + * the stdio functions fread, fseek, fclose, ftell. + * The one difference is that the FILE * arguments have been replaced with + * a void * - this is to be used as a pointer to whatever internal data these + * functions might need. In the stdio case, it's just a FILE * cast to a void * + * + * If you use other functions, check the docs for these functions and return + * the right values. For seek_func(), you *MUST* return -1 if the stream is + * unseekable + */ +typedef struct { + size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); + int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); + int (*close_func) (void *datasource); + long (*tell_func) (void *datasource); +} ov_callbacks; + +#define NOTOPEN 0 +#define PARTOPEN 1 +#define OPENED 2 +#define STREAMSET 3 +#define INITSET 4 + +typedef struct OggVorbis_File { + void *datasource; /* Pointer to a FILE *, etc. */ + int seekable; + ogg_int64_t offset; + ogg_int64_t end; + ogg_sync_state *oy; + + /* If the FILE handle isn't seekable (eg, a pipe), only the current + stream appears */ + int links; + ogg_int64_t *offsets; + ogg_int64_t *dataoffsets; + ogg_uint32_t *serialnos; + ogg_int64_t *pcmlengths; + vorbis_info *vi; + vorbis_comment *vc; + + /* Decoding working state local storage */ + ogg_int64_t pcm_offset; + int ready_state; + ogg_uint32_t current_serialno; + int current_link; + + ogg_int64_t bittrack; + ogg_int64_t samptrack; + + ogg_stream_state *os; /* take physical pages, weld into a logical + stream of packets */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + ov_callbacks callbacks; + +} OggVorbis_File; + +extern int ov_clear(OggVorbis_File *vf); +extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); + +extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); +extern int ov_test_open(OggVorbis_File *vf); + +extern long ov_bitrate(OggVorbis_File *vf,int i); +extern long ov_bitrate_instant(OggVorbis_File *vf); +extern long ov_streams(OggVorbis_File *vf); +extern long ov_seekable(OggVorbis_File *vf); +extern long ov_serialnumber(OggVorbis_File *vf,int i); + +extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i); +extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); +extern ogg_int64_t ov_time_total(OggVorbis_File *vf,int i); + +extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek_page(OggVorbis_File *vf,ogg_int64_t pos); + +extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf); +extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf); +extern ogg_int64_t ov_time_tell(OggVorbis_File *vf); + +extern vorbis_info *ov_info(OggVorbis_File *vf,int link); +extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); + +extern long ov_read(OggVorbis_File *vf,char *buffer,int length, + int *bitstream); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + + diff --git a/genplus-gx/core/tremor/lsp_lookup.h b/genplus-gx/core/tremor/lsp_lookup.h new file mode 100644 index 0000000000..fa84851887 --- /dev/null +++ b/genplus-gx/core/tremor/lsp_lookup.h @@ -0,0 +1,136 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: lookup data + + ********************************************************************/ + +#ifndef _V_LOOKUP_DATA_H_ +#define _V_LOOKUP_DATA_H_ + +#include "os_types.h" + +#define FROMdB_LOOKUP_SZ 35 +#define FROMdB2_LOOKUP_SZ 32 +#define FROMdB_SHIFT 5 +#define FROMdB2_SHIFT 3 +#define FROMdB2_MASK 31 + +static const ogg_int32_t FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={ + 0x003fffff, 0x0028619b, 0x00197a96, 0x0010137a, + 0x000a24b0, 0x00066666, 0x000409c3, 0x00028c42, + 0x00019b8c, 0x000103ab, 0x0000a3d7, 0x00006760, + 0x0000413a, 0x00002928, 0x000019f8, 0x00001062, + 0x00000a56, 0x00000686, 0x0000041e, 0x00000299, + 0x000001a3, 0x00000109, 0x000000a7, 0x00000069, + 0x00000042, 0x0000002a, 0x0000001a, 0x00000011, + 0x0000000b, 0x00000007, 0x00000004, 0x00000003, + 0x00000002, 0x00000001, 0x00000001}; + +static const ogg_int32_t FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={ + 0x000001fc, 0x000001f5, 0x000001ee, 0x000001e7, + 0x000001e0, 0x000001d9, 0x000001d2, 0x000001cc, + 0x000001c5, 0x000001bf, 0x000001b8, 0x000001b2, + 0x000001ac, 0x000001a6, 0x000001a0, 0x0000019a, + 0x00000194, 0x0000018e, 0x00000188, 0x00000183, + 0x0000017d, 0x00000178, 0x00000172, 0x0000016d, + 0x00000168, 0x00000163, 0x0000015e, 0x00000159, + 0x00000154, 0x0000014f, 0x0000014a, 0x00000145, +}; + +#define INVSQ_LOOKUP_I_SHIFT 10 +#define INVSQ_LOOKUP_I_MASK 1023 +static const long INVSQ_LOOKUP_I[64+1]={ + 92682, 91966, 91267, 90583, + 89915, 89261, 88621, 87995, + 87381, 86781, 86192, 85616, + 85051, 84497, 83953, 83420, + 82897, 82384, 81880, 81385, + 80899, 80422, 79953, 79492, + 79039, 78594, 78156, 77726, + 77302, 76885, 76475, 76072, + 75674, 75283, 74898, 74519, + 74146, 73778, 73415, 73058, + 72706, 72359, 72016, 71679, + 71347, 71019, 70695, 70376, + 70061, 69750, 69444, 69141, + 68842, 68548, 68256, 67969, + 67685, 67405, 67128, 66855, + 66585, 66318, 66054, 65794, + 65536, +}; + +static const long INVSQ_LOOKUP_IDel[64]={ + 716, 699, 684, 668, + 654, 640, 626, 614, + 600, 589, 576, 565, + 554, 544, 533, 523, + 513, 504, 495, 486, + 477, 469, 461, 453, + 445, 438, 430, 424, + 417, 410, 403, 398, + 391, 385, 379, 373, + 368, 363, 357, 352, + 347, 343, 337, 332, + 328, 324, 319, 315, + 311, 306, 303, 299, + 294, 292, 287, 284, + 280, 277, 273, 270, + 267, 264, 260, 258, +}; + +#define COS_LOOKUP_I_SHIFT 9 +#define COS_LOOKUP_I_MASK 511 +#define COS_LOOKUP_I_SZ 128 +static const ogg_int32_t COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={ + 16384, 16379, 16364, 16340, + 16305, 16261, 16207, 16143, + 16069, 15986, 15893, 15791, + 15679, 15557, 15426, 15286, + 15137, 14978, 14811, 14635, + 14449, 14256, 14053, 13842, + 13623, 13395, 13160, 12916, + 12665, 12406, 12140, 11866, + 11585, 11297, 11003, 10702, + 10394, 10080, 9760, 9434, + 9102, 8765, 8423, 8076, + 7723, 7366, 7005, 6639, + 6270, 5897, 5520, 5139, + 4756, 4370, 3981, 3590, + 3196, 2801, 2404, 2006, + 1606, 1205, 804, 402, + 0, -401, -803, -1204, + -1605, -2005, -2403, -2800, + -3195, -3589, -3980, -4369, + -4755, -5138, -5519, -5896, + -6269, -6638, -7004, -7365, + -7722, -8075, -8422, -8764, + -9101, -9433, -9759, -10079, + -10393, -10701, -11002, -11296, + -11584, -11865, -12139, -12405, + -12664, -12915, -13159, -13394, + -13622, -13841, -14052, -14255, + -14448, -14634, -14810, -14977, + -15136, -15285, -15425, -15556, + -15678, -15790, -15892, -15985, + -16068, -16142, -16206, -16260, + -16304, -16339, -16363, -16378, + -16383, +}; + +#endif + + + + + diff --git a/genplus-gx/core/tremor/mapping0.c b/genplus-gx/core/tremor/mapping0.c new file mode 100644 index 0000000000..38d14054f8 --- /dev/null +++ b/genplus-gx/core/tremor/mapping0.c @@ -0,0 +1,306 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: channel mapping 0 implementation + + ********************************************************************/ + +#include +#include +#include +#include +#include "ogg.h" +#include "ivorbiscodec.h" +#include "mdct.h" +#include "codec_internal.h" +#include "codebook.h" +#include "window.h" +#include "registry.h" +#include "misc.h" + +/* simplistic, wasteful way of doing this (unique lookup for each + mode/submapping); there should be a central repository for + identical lookups. That will require minor work, so I'm putting it + off as low priority. + + Why a lookup for each backend in a given mode? Because the + blocksize is set by the mode, and low backend lookups may require + parameters from other areas of the mode/mapping */ + +typedef struct { + vorbis_info_mode *mode; + vorbis_info_mapping0 *map; + + vorbis_look_floor **floor_look; + + vorbis_look_residue **residue_look; + + vorbis_func_floor **floor_func; + vorbis_func_residue **residue_func; + + int ch; + long lastframe; /* if a different mode is called, we need to + invalidate decay */ +} vorbis_look_mapping0; + +static void mapping0_free_info(vorbis_info_mapping *i){ + vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +static void mapping0_free_look(vorbis_look_mapping *look){ + int i; + vorbis_look_mapping0 *l=(vorbis_look_mapping0 *)look; + if(l){ + + for(i=0;imap->submaps;i++){ + l->floor_func[i]->free_look(l->floor_look[i]); + l->residue_func[i]->free_look(l->residue_look[i]); + } + + _ogg_free(l->floor_func); + _ogg_free(l->residue_func); + _ogg_free(l->floor_look); + _ogg_free(l->residue_look); + memset(l,0,sizeof(*l)); + _ogg_free(l); + } +} + +static vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm, + vorbis_info_mapping *m){ + int i; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)_ogg_calloc(1,sizeof(*look)); + vorbis_info_mapping0 *info=look->map=(vorbis_info_mapping0 *)m; + look->mode=vm; + + look->floor_look=(vorbis_look_floor **)_ogg_calloc(info->submaps,sizeof(*look->floor_look)); + + look->residue_look=(vorbis_look_residue **)_ogg_calloc(info->submaps,sizeof(*look->residue_look)); + + look->floor_func=(vorbis_func_floor **)_ogg_calloc(info->submaps,sizeof(*look->floor_func)); + look->residue_func=(vorbis_func_residue **)_ogg_calloc(info->submaps,sizeof(*look->residue_func)); + + for(i=0;isubmaps;i++){ + int floornum=info->floorsubmap[i]; + int resnum=info->residuesubmap[i]; + + look->floor_func[i]=_floor_P[ci->floor_type[floornum]]; + look->floor_look[i]=look->floor_func[i]-> + look(vd,vm,ci->floor_param[floornum]); + look->residue_func[i]=_residue_P[ci->residue_type[resnum]]; + look->residue_look[i]=look->residue_func[i]-> + look(vd,vm,ci->residue_param[resnum]); + + } + + look->ch=vi->channels; + + return(look); +} + +static int ilog(unsigned int v){ + int ret=0; + if(v)--v; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +/* also responsible for range checking */ +static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){ + int i; + vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)_ogg_calloc(1,sizeof(*info)); + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + memset(info,0,sizeof(*info)); + + if(oggpack_read(opb,1)) + info->submaps=oggpack_read(opb,4)+1; + else + info->submaps=1; + + if(oggpack_read(opb,1)){ + info->coupling_steps=oggpack_read(opb,8)+1; + + for(i=0;icoupling_steps;i++){ + int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels)); + int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels)); + + if(testM<0 || + testA<0 || + testM==testA || + testM>=vi->channels || + testA>=vi->channels) goto err_out; + } + + } + + if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */ + + if(info->submaps>1){ + for(i=0;ichannels;i++){ + info->chmuxlist[i]=oggpack_read(opb,4); + if(info->chmuxlist[i]>=info->submaps)goto err_out; + } + } + for(i=0;isubmaps;i++){ + int temp=oggpack_read(opb,8); + if(temp>=ci->times)goto err_out; + info->floorsubmap[i]=oggpack_read(opb,8); + if(info->floorsubmap[i]>=ci->floors)goto err_out; + info->residuesubmap[i]=oggpack_read(opb,8); + if(info->residuesubmap[i]>=ci->residues)goto err_out; + } + + return info; + + err_out: + mapping0_free_info(info); + return(NULL); +} + +static int seq=0; +static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){ + vorbis_dsp_state *vd=vb->vd; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + private_state *b=(private_state *)vd->backend_state; + vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l; + vorbis_info_mapping0 *info=look->map; + + int i,j; + long n=vb->pcmend=ci->blocksizes[vb->W]; + + ogg_int32_t **pcmbundle=(ogg_int32_t **)alloca(sizeof(*pcmbundle)*vi->channels); + int *zerobundle=(int *)alloca(sizeof(*zerobundle)*vi->channels); + + int *nonzero =(int *)alloca(sizeof(*nonzero)*vi->channels); + void **floormemo=(void **)alloca(sizeof(*floormemo)*vi->channels); + + /* time domain information decode (note that applying the + information would have to happen later; we'll probably add a + function entry to the harness for that later */ + /* NOT IMPLEMENTED */ + + /* recover the spectral envelope; store it in the PCM vector for now */ + for(i=0;ichannels;i++){ + int submap=info->chmuxlist[i]; + floormemo[i]=look->floor_func[submap]-> + inverse1(vb,look->floor_look[submap]); + if(floormemo[i]) + nonzero[i]=1; + else + nonzero[i]=0; + memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2); + } + + /* channel coupling can 'dirty' the nonzero listing */ + for(i=0;icoupling_steps;i++){ + if(nonzero[info->coupling_mag[i]] || + nonzero[info->coupling_ang[i]]){ + nonzero[info->coupling_mag[i]]=1; + nonzero[info->coupling_ang[i]]=1; + } + } + + /* recover the residue into our working vectors */ + for(i=0;isubmaps;i++){ + int ch_in_bundle=0; + for(j=0;jchannels;j++){ + if(info->chmuxlist[j]==i){ + if(nonzero[j]) + zerobundle[ch_in_bundle]=1; + else + zerobundle[ch_in_bundle]=0; + pcmbundle[ch_in_bundle++]=vb->pcm[j]; + } + } + + look->residue_func[i]->inverse(vb,look->residue_look[i], + pcmbundle,zerobundle,ch_in_bundle); + } + + /* channel coupling */ + for(i=info->coupling_steps-1;i>=0;i--){ + ogg_int32_t *pcmM=vb->pcm[info->coupling_mag[i]]; + ogg_int32_t *pcmA=vb->pcm[info->coupling_ang[i]]; + + for(j=0;j0) + if(ang>0){ + pcmM[j]=mag; + pcmA[j]=mag-ang; + }else{ + pcmA[j]=mag; + pcmM[j]=mag+ang; + } + else + if(ang>0){ + pcmM[j]=mag; + pcmA[j]=mag+ang; + }else{ + pcmA[j]=mag; + pcmM[j]=mag-ang; + } + } + } + + /* compute and apply spectral envelope */ + for(i=0;ichannels;i++){ + ogg_int32_t *pcm=vb->pcm[i]; + int submap=info->chmuxlist[i]; + look->floor_func[submap]-> + inverse2(vb,look->floor_look[submap],floormemo[i],pcm); + } + + /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */ + /* only MDCT right now.... */ + for(i=0;ichannels;i++){ + ogg_int32_t *pcm=vb->pcm[i]; + mdct_backward(n,pcm,pcm); + } + + /* window the data */ + for(i=0;ichannels;i++){ + ogg_int32_t *pcm=vb->pcm[i]; + if(nonzero[i]) + _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW); + else + for(j=0;jchannels; + /* all done! */ + return(0); +} + +/* export hooks */ +vorbis_func_mapping mapping0_exportbundle={ + &mapping0_unpack, + &mapping0_look, + &mapping0_free_info, + &mapping0_free_look, + &mapping0_inverse +}; diff --git a/genplus-gx/core/tremor/mdct.c b/genplus-gx/core/tremor/mdct.c new file mode 100644 index 0000000000..4f39e7d531 --- /dev/null +++ b/genplus-gx/core/tremor/mdct.c @@ -0,0 +1,510 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: normalized modified discrete cosine transform + power of two length transform only [64 <= n ] + last mod: $Id: mdct.c,v 1.9 2002/10/16 09:17:39 xiphmont Exp $ + + Original algorithm adapted long ago from _The use of multirate filter + banks for coding of high quality digital audio_, by T. Sporer, + K. Brandenburg and B. Edler, collection of the European Signal + Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp + 211-214 + + The below code implements an algorithm that no longer looks much like + that presented in the paper, but the basic structure remains if you + dig deep enough to see it. + + This module DOES NOT INCLUDE code to generate/apply the window + function. Everybody has their own weird favorite including me... I + happen to like the properties of y=sin(.5PI*sin^2(x)), but others may + vehemently disagree. + + ********************************************************************/ + +#include "ivorbiscodec.h" +#include "codebook.h" +#include "misc.h" +#include "mdct.h" +#include "mdct_lookup.h" + + +/* 8 point butterfly (in place) */ +STIN void mdct_butterfly_8(DATA_TYPE *x){ + + REG_TYPE r0 = x[4] + x[0]; + REG_TYPE r1 = x[4] - x[0]; + REG_TYPE r2 = x[5] + x[1]; + REG_TYPE r3 = x[5] - x[1]; + REG_TYPE r4 = x[6] + x[2]; + REG_TYPE r5 = x[6] - x[2]; + REG_TYPE r6 = x[7] + x[3]; + REG_TYPE r7 = x[7] - x[3]; + + x[0] = r5 + r3; + x[1] = r7 - r1; + x[2] = r5 - r3; + x[3] = r7 + r1; + x[4] = r4 - r0; + x[5] = r6 - r2; + x[6] = r4 + r0; + x[7] = r6 + r2; + MB(); +} + +/* 16 point butterfly (in place, 4 register) */ +STIN void mdct_butterfly_16(DATA_TYPE *x){ + + REG_TYPE r0, r1; + + r0 = x[ 0] - x[ 8]; x[ 8] += x[ 0]; + r1 = x[ 1] - x[ 9]; x[ 9] += x[ 1]; + x[ 0] = MULT31((r0 + r1) , cPI2_8); + x[ 1] = MULT31((r1 - r0) , cPI2_8); + MB(); + + r0 = x[10] - x[ 2]; x[10] += x[ 2]; + r1 = x[ 3] - x[11]; x[11] += x[ 3]; + x[ 2] = r1; x[ 3] = r0; + MB(); + + r0 = x[12] - x[ 4]; x[12] += x[ 4]; + r1 = x[13] - x[ 5]; x[13] += x[ 5]; + x[ 4] = MULT31((r0 - r1) , cPI2_8); + x[ 5] = MULT31((r0 + r1) , cPI2_8); + MB(); + + r0 = x[14] - x[ 6]; x[14] += x[ 6]; + r1 = x[15] - x[ 7]; x[15] += x[ 7]; + x[ 6] = r0; x[ 7] = r1; + MB(); + + mdct_butterfly_8(x); + mdct_butterfly_8(x+8); +} + +/* 32 point butterfly (in place, 4 register) */ +STIN void mdct_butterfly_32(DATA_TYPE *x){ + + REG_TYPE r0, r1; + + r0 = x[30] - x[14]; x[30] += x[14]; + r1 = x[31] - x[15]; x[31] += x[15]; + x[14] = r0; x[15] = r1; + MB(); + + r0 = x[28] - x[12]; x[28] += x[12]; + r1 = x[29] - x[13]; x[29] += x[13]; + XNPROD31( r0, r1, cPI1_8, cPI3_8, &x[12], &x[13] ); + MB(); + + r0 = x[26] - x[10]; x[26] += x[10]; + r1 = x[27] - x[11]; x[27] += x[11]; + x[10] = MULT31((r0 - r1) , cPI2_8); + x[11] = MULT31((r0 + r1) , cPI2_8); + MB(); + + r0 = x[24] - x[ 8]; x[24] += x[ 8]; + r1 = x[25] - x[ 9]; x[25] += x[ 9]; + XNPROD31( r0, r1, cPI3_8, cPI1_8, &x[ 8], &x[ 9] ); + MB(); + + r0 = x[22] - x[ 6]; x[22] += x[ 6]; + r1 = x[ 7] - x[23]; x[23] += x[ 7]; + x[ 6] = r1; x[ 7] = r0; + MB(); + + r0 = x[ 4] - x[20]; x[20] += x[ 4]; + r1 = x[ 5] - x[21]; x[21] += x[ 5]; + XPROD31 ( r0, r1, cPI3_8, cPI1_8, &x[ 4], &x[ 5] ); + MB(); + + r0 = x[ 2] - x[18]; x[18] += x[ 2]; + r1 = x[ 3] - x[19]; x[19] += x[ 3]; + x[ 2] = MULT31((r1 + r0) , cPI2_8); + x[ 3] = MULT31((r1 - r0) , cPI2_8); + MB(); + + r0 = x[ 0] - x[16]; x[16] += x[ 0]; + r1 = x[ 1] - x[17]; x[17] += x[ 1]; + XPROD31 ( r0, r1, cPI1_8, cPI3_8, &x[ 0], &x[ 1] ); + MB(); + + mdct_butterfly_16(x); + mdct_butterfly_16(x+16); +} + +/* N/stage point generic N stage butterfly (in place, 2 register) */ +STIN void mdct_butterfly_generic(DATA_TYPE *x,int points,int step){ + + LOOKUP_T *T = sincos_lookup0; + DATA_TYPE *x1 = x + points - 8; + DATA_TYPE *x2 = x + (points>>1) - 8; + REG_TYPE r0; + REG_TYPE r1; + + do{ + r0 = x1[6] - x2[6]; x1[6] += x2[6]; + r1 = x2[7] - x1[7]; x1[7] += x2[7]; + XPROD31( r1, r0, T[0], T[1], &x2[6], &x2[7] ); T+=step; + + r0 = x1[4] - x2[4]; x1[4] += x2[4]; + r1 = x2[5] - x1[5]; x1[5] += x2[5]; + XPROD31( r1, r0, T[0], T[1], &x2[4], &x2[5] ); T+=step; + + r0 = x1[2] - x2[2]; x1[2] += x2[2]; + r1 = x2[3] - x1[3]; x1[3] += x2[3]; + XPROD31( r1, r0, T[0], T[1], &x2[2], &x2[3] ); T+=step; + + r0 = x1[0] - x2[0]; x1[0] += x2[0]; + r1 = x2[1] - x1[1]; x1[1] += x2[1]; + XPROD31( r1, r0, T[0], T[1], &x2[0], &x2[1] ); T+=step; + + x1-=8; x2-=8; + }while(Tsincos_lookup0); + do{ + r0 = x2[6] - x1[6]; x1[6] += x2[6]; + r1 = x2[7] - x1[7]; x1[7] += x2[7]; + XPROD31( r0, r1, T[0], T[1], &x2[6], &x2[7] ); T+=step; + + r0 = x2[4] - x1[4]; x1[4] += x2[4]; + r1 = x2[5] - x1[5]; x1[5] += x2[5]; + XPROD31( r0, r1, T[0], T[1], &x2[4], &x2[5] ); T+=step; + + r0 = x2[2] - x1[2]; x1[2] += x2[2]; + r1 = x2[3] - x1[3]; x1[3] += x2[3]; + XPROD31( r0, r1, T[0], T[1], &x2[2], &x2[3] ); T+=step; + + r0 = x2[0] - x1[0]; x1[0] += x2[0]; + r1 = x2[1] - x1[1]; x1[1] += x2[1]; + XPROD31( r0, r1, T[0], T[1], &x2[0], &x2[1] ); T+=step; + + x1-=8; x2-=8; + }while(Tsincos_lookup0); +} + +STIN void mdct_butterflies(DATA_TYPE *x,int points,int shift){ + + int stages=8-shift; + int i,j; + + for(i=0;--stages>0;i++){ + for(j=0;j<(1<>i)*j,points>>i,4<<(i+shift)); + } + + for(j=0;j>8]|(bitrev[(x&0x0f0)>>4]<<4)|(((int)bitrev[x&0x00f])<<8); +} + +STIN void mdct_bitreverse(DATA_TYPE *x,int n,int step,int shift){ + + int bit = 0; + DATA_TYPE *w0 = x; + DATA_TYPE *w1 = x = w0+(n>>1); + LOOKUP_T *T = (step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1; + LOOKUP_T *Ttop = T+1024; + DATA_TYPE r2; + + do{ + DATA_TYPE r3 = bitrev12(bit++); + DATA_TYPE *x0 = x + ((r3 ^ 0xfff)>>shift) -1; + DATA_TYPE *x1 = x + (r3>>shift); + + REG_TYPE r0 = x0[0] + x1[0]; + REG_TYPE r1 = x1[1] - x0[1]; + + XPROD32( r0, r1, T[1], T[0], &r2, &r3 ); T+=step; + + w1 -= 4; + + r0 = (x0[1] + x1[1])>>1; + r1 = (x0[0] - x1[0])>>1; + w0[0] = r0 + r2; + w0[1] = r1 + r3; + w1[2] = r0 - r2; + w1[3] = r3 - r1; + + r3 = bitrev12(bit++); + x0 = x + ((r3 ^ 0xfff)>>shift) -1; + x1 = x + (r3>>shift); + + r0 = x0[0] + x1[0]; + r1 = x1[1] - x0[1]; + + XPROD32( r0, r1, T[1], T[0], &r2, &r3 ); T+=step; + + r0 = (x0[1] + x1[1])>>1; + r1 = (x0[0] - x1[0])>>1; + w0[2] = r0 + r2; + w0[3] = r1 + r3; + w1[0] = r0 - r2; + w1[1] = r3 - r1; + + w0 += 4; + }while(T>shift) -1; + DATA_TYPE *x1 = x + (r3>>shift); + + REG_TYPE r0 = x0[0] + x1[0]; + REG_TYPE r1 = x1[1] - x0[1]; + + T-=step; XPROD32( r0, r1, T[0], T[1], &r2, &r3 ); + + w1 -= 4; + + r0 = (x0[1] + x1[1])>>1; + r1 = (x0[0] - x1[0])>>1; + w0[0] = r0 + r2; + w0[1] = r1 + r3; + w1[2] = r0 - r2; + w1[3] = r3 - r1; + + r3 = bitrev12(bit++); + x0 = x + ((r3 ^ 0xfff)>>shift) -1; + x1 = x + (r3>>shift); + + r0 = x0[0] + x1[0]; + r1 = x1[1] - x0[1]; + + T-=step; XPROD32( r0, r1, T[0], T[1], &r2, &r3 ); + + r0 = (x0[1] + x1[1])>>1; + r1 = (x0[0] - x1[0])>>1; + w0[2] = r0 + r2; + w0[3] = r1 + r3; + w1[0] = r0 - r2; + w1[1] = r3 - r1; + + w0 += 4; + }while(w0>1; + int n4=n>>2; + DATA_TYPE *iX; + DATA_TYPE *oX; + LOOKUP_T *T; + LOOKUP_T *V; + int shift; + int step; + + for (shift=6;!(n&(1<=in+n4); + do{ + oX-=4; + XPROD31( iX[4], iX[6], T[1], T[0], &oX[2], &oX[3] ); T-=step; + XPROD31( iX[0], iX[2], T[1], T[0], &oX[0], &oX[1] ); T-=step; + iX-=8; + }while(iX>=in); + + iX = in+n2-8; + oX = out+n2+n4; + T = sincos_lookup0; + + do{ + T+=step; XNPROD31( iX[6], iX[4], T[0], T[1], &oX[0], &oX[1] ); + T+=step; XNPROD31( iX[2], iX[0], T[0], T[1], &oX[2], &oX[3] ); + iX-=8; + oX+=4; + }while(iX>=in+n4); + do{ + T-=step; XNPROD31( iX[6], iX[4], T[1], T[0], &oX[0], &oX[1] ); + T-=step; XNPROD31( iX[2], iX[0], T[1], T[0], &oX[2], &oX[3] ); + iX-=8; + oX+=4; + }while(iX>=in); + + mdct_butterflies(out+n2,n2,shift); + mdct_bitreverse(out,n,step,shift); + + /* rotate + window */ + + step>>=2; + { + DATA_TYPE *oX1=out+n2+n4; + DATA_TYPE *oX2=out+n2+n4; + DATA_TYPE *iX =out; + + switch(step) { + default: { + T=(step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1; + do{ + oX1-=4; + XPROD31( iX[0], -iX[1], T[0], T[1], &oX1[3], &oX2[0] ); T+=step; + XPROD31( iX[2], -iX[3], T[0], T[1], &oX1[2], &oX2[1] ); T+=step; + XPROD31( iX[4], -iX[5], T[0], T[1], &oX1[1], &oX2[2] ); T+=step; + XPROD31( iX[6], -iX[7], T[0], T[1], &oX1[0], &oX2[3] ); T+=step; + oX2+=4; + iX+=8; + }while(iX>1; + t1 = (*T++)>>1; + do{ + oX1-=4; + + t0 += (v0 = (*V++)>>1); + t1 += (v1 = (*V++)>>1); + XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] ); + v0 += (t0 = (*T++)>>1); + v1 += (t1 = (*T++)>>1); + XPROD31( iX[2], -iX[3], v0, v1, &oX1[2], &oX2[1] ); + t0 += (v0 = (*V++)>>1); + t1 += (v1 = (*V++)>>1); + XPROD31( iX[4], -iX[5], t0, t1, &oX1[1], &oX2[2] ); + v0 += (t0 = (*T++)>>1); + v1 += (t1 = (*T++)>>1); + XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] ); + + oX2+=4; + iX+=8; + }while(iX>2); + t1 += (q1 = (v1-t1)>>2); + XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] ); + t0 = v0-q0; + t1 = v1-q1; + XPROD31( iX[2], -iX[3], t0, t1, &oX1[2], &oX2[1] ); + + t0 = *T++; + t1 = *T++; + v0 += (q0 = (t0-v0)>>2); + v1 += (q1 = (t1-v1)>>2); + XPROD31( iX[4], -iX[5], v0, v1, &oX1[1], &oX2[2] ); + v0 = t0-q0; + v1 = t1-q1; + XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] ); + + oX2+=4; + iX+=8; + }while(iXoX2); + } +} + diff --git a/genplus-gx/core/tremor/mdct.h b/genplus-gx/core/tremor/mdct.h new file mode 100644 index 0000000000..6d8890720c --- /dev/null +++ b/genplus-gx/core/tremor/mdct.h @@ -0,0 +1,52 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: modified discrete cosine transform prototypes + + ********************************************************************/ + +#ifndef _OGG_mdct_H_ +#define _OGG_mdct_H_ + +#include "ivorbiscodec.h" +#include "misc.h" + +#define DATA_TYPE ogg_int32_t +#define REG_TYPE register ogg_int32_t + +#ifdef _LOW_ACCURACY_ +#define cPI3_8 (0x0062) +#define cPI2_8 (0x00b5) +#define cPI1_8 (0x00ed) +#else +#define cPI3_8 (0x30fbc54d) +#define cPI2_8 (0x5a82799a) +#define cPI1_8 (0x7641af3d) +#endif + +extern void mdct_forward(int n, DATA_TYPE *in, DATA_TYPE *out); +extern void mdct_backward(int n, DATA_TYPE *in, DATA_TYPE *out); + +#endif + + + + + + + + + + + + diff --git a/genplus-gx/core/tremor/mdct_lookup.h b/genplus-gx/core/tremor/mdct_lookup.h new file mode 100644 index 0000000000..970e199f7f --- /dev/null +++ b/genplus-gx/core/tremor/mdct_lookup.h @@ -0,0 +1,540 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: sin,cos lookup tables + + ********************************************************************/ + +#include "os_types.h" + +/* {sin(2*i*PI/4096), cos(2*i*PI/4096)}, with i = 0 to 512 */ +static LOOKUP_T sincos_lookup0[1026] = { + X(0x00000000), X(0x7fffffff), X(0x003243f5), X(0x7ffff621), + X(0x006487e3), X(0x7fffd886), X(0x0096cbc1), X(0x7fffa72c), + X(0x00c90f88), X(0x7fff6216), X(0x00fb5330), X(0x7fff0943), + X(0x012d96b1), X(0x7ffe9cb2), X(0x015fda03), X(0x7ffe1c65), + X(0x01921d20), X(0x7ffd885a), X(0x01c45ffe), X(0x7ffce093), + X(0x01f6a297), X(0x7ffc250f), X(0x0228e4e2), X(0x7ffb55ce), + X(0x025b26d7), X(0x7ffa72d1), X(0x028d6870), X(0x7ff97c18), + X(0x02bfa9a4), X(0x7ff871a2), X(0x02f1ea6c), X(0x7ff75370), + X(0x03242abf), X(0x7ff62182), X(0x03566a96), X(0x7ff4dbd9), + X(0x0388a9ea), X(0x7ff38274), X(0x03bae8b2), X(0x7ff21553), + X(0x03ed26e6), X(0x7ff09478), X(0x041f6480), X(0x7feeffe1), + X(0x0451a177), X(0x7fed5791), X(0x0483ddc3), X(0x7feb9b85), + X(0x04b6195d), X(0x7fe9cbc0), X(0x04e8543e), X(0x7fe7e841), + X(0x051a8e5c), X(0x7fe5f108), X(0x054cc7b1), X(0x7fe3e616), + X(0x057f0035), X(0x7fe1c76b), X(0x05b137df), X(0x7fdf9508), + X(0x05e36ea9), X(0x7fdd4eec), X(0x0615a48b), X(0x7fdaf519), + X(0x0647d97c), X(0x7fd8878e), X(0x067a0d76), X(0x7fd6064c), + X(0x06ac406f), X(0x7fd37153), X(0x06de7262), X(0x7fd0c8a3), + X(0x0710a345), X(0x7fce0c3e), X(0x0742d311), X(0x7fcb3c23), + X(0x077501be), X(0x7fc85854), X(0x07a72f45), X(0x7fc560cf), + X(0x07d95b9e), X(0x7fc25596), X(0x080b86c2), X(0x7fbf36aa), + X(0x083db0a7), X(0x7fbc040a), X(0x086fd947), X(0x7fb8bdb8), + X(0x08a2009a), X(0x7fb563b3), X(0x08d42699), X(0x7fb1f5fc), + X(0x09064b3a), X(0x7fae7495), X(0x09386e78), X(0x7faadf7c), + X(0x096a9049), X(0x7fa736b4), X(0x099cb0a7), X(0x7fa37a3c), + X(0x09cecf89), X(0x7f9faa15), X(0x0a00ece8), X(0x7f9bc640), + X(0x0a3308bd), X(0x7f97cebd), X(0x0a6522fe), X(0x7f93c38c), + X(0x0a973ba5), X(0x7f8fa4b0), X(0x0ac952aa), X(0x7f8b7227), + X(0x0afb6805), X(0x7f872bf3), X(0x0b2d7baf), X(0x7f82d214), + X(0x0b5f8d9f), X(0x7f7e648c), X(0x0b919dcf), X(0x7f79e35a), + X(0x0bc3ac35), X(0x7f754e80), X(0x0bf5b8cb), X(0x7f70a5fe), + X(0x0c27c389), X(0x7f6be9d4), X(0x0c59cc68), X(0x7f671a05), + X(0x0c8bd35e), X(0x7f62368f), X(0x0cbdd865), X(0x7f5d3f75), + X(0x0cefdb76), X(0x7f5834b7), X(0x0d21dc87), X(0x7f531655), + X(0x0d53db92), X(0x7f4de451), X(0x0d85d88f), X(0x7f489eaa), + X(0x0db7d376), X(0x7f434563), X(0x0de9cc40), X(0x7f3dd87c), + X(0x0e1bc2e4), X(0x7f3857f6), X(0x0e4db75b), X(0x7f32c3d1), + X(0x0e7fa99e), X(0x7f2d1c0e), X(0x0eb199a4), X(0x7f2760af), + X(0x0ee38766), X(0x7f2191b4), X(0x0f1572dc), X(0x7f1baf1e), + X(0x0f475bff), X(0x7f15b8ee), X(0x0f7942c7), X(0x7f0faf25), + X(0x0fab272b), X(0x7f0991c4), X(0x0fdd0926), X(0x7f0360cb), + X(0x100ee8ad), X(0x7efd1c3c), X(0x1040c5bb), X(0x7ef6c418), + X(0x1072a048), X(0x7ef05860), X(0x10a4784b), X(0x7ee9d914), + X(0x10d64dbd), X(0x7ee34636), X(0x11082096), X(0x7edc9fc6), + X(0x1139f0cf), X(0x7ed5e5c6), X(0x116bbe60), X(0x7ecf1837), + X(0x119d8941), X(0x7ec8371a), X(0x11cf516a), X(0x7ec14270), + X(0x120116d5), X(0x7eba3a39), X(0x1232d979), X(0x7eb31e78), + X(0x1264994e), X(0x7eabef2c), X(0x1296564d), X(0x7ea4ac58), + X(0x12c8106f), X(0x7e9d55fc), X(0x12f9c7aa), X(0x7e95ec1a), + X(0x132b7bf9), X(0x7e8e6eb2), X(0x135d2d53), X(0x7e86ddc6), + X(0x138edbb1), X(0x7e7f3957), X(0x13c0870a), X(0x7e778166), + X(0x13f22f58), X(0x7e6fb5f4), X(0x1423d492), X(0x7e67d703), + X(0x145576b1), X(0x7e5fe493), X(0x148715ae), X(0x7e57dea7), + X(0x14b8b17f), X(0x7e4fc53e), X(0x14ea4a1f), X(0x7e47985b), + X(0x151bdf86), X(0x7e3f57ff), X(0x154d71aa), X(0x7e37042a), + X(0x157f0086), X(0x7e2e9cdf), X(0x15b08c12), X(0x7e26221f), + X(0x15e21445), X(0x7e1d93ea), X(0x16139918), X(0x7e14f242), + X(0x16451a83), X(0x7e0c3d29), X(0x1676987f), X(0x7e0374a0), + X(0x16a81305), X(0x7dfa98a8), X(0x16d98a0c), X(0x7df1a942), + X(0x170afd8d), X(0x7de8a670), X(0x173c6d80), X(0x7ddf9034), + X(0x176dd9de), X(0x7dd6668f), X(0x179f429f), X(0x7dcd2981), + X(0x17d0a7bc), X(0x7dc3d90d), X(0x1802092c), X(0x7dba7534), + X(0x183366e9), X(0x7db0fdf8), X(0x1864c0ea), X(0x7da77359), + X(0x18961728), X(0x7d9dd55a), X(0x18c7699b), X(0x7d9423fc), + X(0x18f8b83c), X(0x7d8a5f40), X(0x192a0304), X(0x7d808728), + X(0x195b49ea), X(0x7d769bb5), X(0x198c8ce7), X(0x7d6c9ce9), + X(0x19bdcbf3), X(0x7d628ac6), X(0x19ef0707), X(0x7d58654d), + X(0x1a203e1b), X(0x7d4e2c7f), X(0x1a517128), X(0x7d43e05e), + X(0x1a82a026), X(0x7d3980ec), X(0x1ab3cb0d), X(0x7d2f0e2b), + X(0x1ae4f1d6), X(0x7d24881b), X(0x1b161479), X(0x7d19eebf), + X(0x1b4732ef), X(0x7d0f4218), X(0x1b784d30), X(0x7d048228), + X(0x1ba96335), X(0x7cf9aef0), X(0x1bda74f6), X(0x7ceec873), + X(0x1c0b826a), X(0x7ce3ceb2), X(0x1c3c8b8c), X(0x7cd8c1ae), + X(0x1c6d9053), X(0x7ccda169), X(0x1c9e90b8), X(0x7cc26de5), + X(0x1ccf8cb3), X(0x7cb72724), X(0x1d00843d), X(0x7cabcd28), + X(0x1d31774d), X(0x7ca05ff1), X(0x1d6265dd), X(0x7c94df83), + X(0x1d934fe5), X(0x7c894bde), X(0x1dc4355e), X(0x7c7da505), + X(0x1df5163f), X(0x7c71eaf9), X(0x1e25f282), X(0x7c661dbc), + X(0x1e56ca1e), X(0x7c5a3d50), X(0x1e879d0d), X(0x7c4e49b7), + X(0x1eb86b46), X(0x7c4242f2), X(0x1ee934c3), X(0x7c362904), + X(0x1f19f97b), X(0x7c29fbee), X(0x1f4ab968), X(0x7c1dbbb3), + X(0x1f7b7481), X(0x7c116853), X(0x1fac2abf), X(0x7c0501d2), + X(0x1fdcdc1b), X(0x7bf88830), X(0x200d888d), X(0x7bebfb70), + X(0x203e300d), X(0x7bdf5b94), X(0x206ed295), X(0x7bd2a89e), + X(0x209f701c), X(0x7bc5e290), X(0x20d0089c), X(0x7bb9096b), + X(0x21009c0c), X(0x7bac1d31), X(0x21312a65), X(0x7b9f1de6), + X(0x2161b3a0), X(0x7b920b89), X(0x219237b5), X(0x7b84e61f), + X(0x21c2b69c), X(0x7b77ada8), X(0x21f3304f), X(0x7b6a6227), + X(0x2223a4c5), X(0x7b5d039e), X(0x225413f8), X(0x7b4f920e), + X(0x22847de0), X(0x7b420d7a), X(0x22b4e274), X(0x7b3475e5), + X(0x22e541af), X(0x7b26cb4f), X(0x23159b88), X(0x7b190dbc), + X(0x2345eff8), X(0x7b0b3d2c), X(0x23763ef7), X(0x7afd59a4), + X(0x23a6887f), X(0x7aef6323), X(0x23d6cc87), X(0x7ae159ae), + X(0x24070b08), X(0x7ad33d45), X(0x243743fa), X(0x7ac50dec), + X(0x24677758), X(0x7ab6cba4), X(0x2497a517), X(0x7aa8766f), + X(0x24c7cd33), X(0x7a9a0e50), X(0x24f7efa2), X(0x7a8b9348), + X(0x25280c5e), X(0x7a7d055b), X(0x2558235f), X(0x7a6e648a), + X(0x2588349d), X(0x7a5fb0d8), X(0x25b84012), X(0x7a50ea47), + X(0x25e845b6), X(0x7a4210d8), X(0x26184581), X(0x7a332490), + X(0x26483f6c), X(0x7a24256f), X(0x26783370), X(0x7a151378), + X(0x26a82186), X(0x7a05eead), X(0x26d809a5), X(0x79f6b711), + X(0x2707ebc7), X(0x79e76ca7), X(0x2737c7e3), X(0x79d80f6f), + X(0x27679df4), X(0x79c89f6e), X(0x27976df1), X(0x79b91ca4), + X(0x27c737d3), X(0x79a98715), X(0x27f6fb92), X(0x7999dec4), + X(0x2826b928), X(0x798a23b1), X(0x2856708d), X(0x797a55e0), + X(0x288621b9), X(0x796a7554), X(0x28b5cca5), X(0x795a820e), + X(0x28e5714b), X(0x794a7c12), X(0x29150fa1), X(0x793a6361), + X(0x2944a7a2), X(0x792a37fe), X(0x29743946), X(0x7919f9ec), + X(0x29a3c485), X(0x7909a92d), X(0x29d34958), X(0x78f945c3), + X(0x2a02c7b8), X(0x78e8cfb2), X(0x2a323f9e), X(0x78d846fb), + X(0x2a61b101), X(0x78c7aba2), X(0x2a911bdc), X(0x78b6fda8), + X(0x2ac08026), X(0x78a63d11), X(0x2aefddd8), X(0x789569df), + X(0x2b1f34eb), X(0x78848414), X(0x2b4e8558), X(0x78738bb3), + X(0x2b7dcf17), X(0x786280bf), X(0x2bad1221), X(0x7851633b), + X(0x2bdc4e6f), X(0x78403329), X(0x2c0b83fa), X(0x782ef08b), + X(0x2c3ab2b9), X(0x781d9b65), X(0x2c69daa6), X(0x780c33b8), + X(0x2c98fbba), X(0x77fab989), X(0x2cc815ee), X(0x77e92cd9), + X(0x2cf72939), X(0x77d78daa), X(0x2d263596), X(0x77c5dc01), + X(0x2d553afc), X(0x77b417df), X(0x2d843964), X(0x77a24148), + X(0x2db330c7), X(0x7790583e), X(0x2de2211e), X(0x777e5cc3), + X(0x2e110a62), X(0x776c4edb), X(0x2e3fec8b), X(0x775a2e89), + X(0x2e6ec792), X(0x7747fbce), X(0x2e9d9b70), X(0x7735b6af), + X(0x2ecc681e), X(0x77235f2d), X(0x2efb2d95), X(0x7710f54c), + X(0x2f29ebcc), X(0x76fe790e), X(0x2f58a2be), X(0x76ebea77), + X(0x2f875262), X(0x76d94989), X(0x2fb5fab2), X(0x76c69647), + X(0x2fe49ba7), X(0x76b3d0b4), X(0x30133539), X(0x76a0f8d2), + X(0x3041c761), X(0x768e0ea6), X(0x30705217), X(0x767b1231), + X(0x309ed556), X(0x76680376), X(0x30cd5115), X(0x7654e279), + X(0x30fbc54d), X(0x7641af3d), X(0x312a31f8), X(0x762e69c4), + X(0x3158970e), X(0x761b1211), X(0x3186f487), X(0x7607a828), + X(0x31b54a5e), X(0x75f42c0b), X(0x31e39889), X(0x75e09dbd), + X(0x3211df04), X(0x75ccfd42), X(0x32401dc6), X(0x75b94a9c), + X(0x326e54c7), X(0x75a585cf), X(0x329c8402), X(0x7591aedd), + X(0x32caab6f), X(0x757dc5ca), X(0x32f8cb07), X(0x7569ca99), + X(0x3326e2c3), X(0x7555bd4c), X(0x3354f29b), X(0x75419de7), + X(0x3382fa88), X(0x752d6c6c), X(0x33b0fa84), X(0x751928e0), + X(0x33def287), X(0x7504d345), X(0x340ce28b), X(0x74f06b9e), + X(0x343aca87), X(0x74dbf1ef), X(0x3468aa76), X(0x74c7663a), + X(0x34968250), X(0x74b2c884), X(0x34c4520d), X(0x749e18cd), + X(0x34f219a8), X(0x7489571c), X(0x351fd918), X(0x74748371), + X(0x354d9057), X(0x745f9dd1), X(0x357b3f5d), X(0x744aa63f), + X(0x35a8e625), X(0x74359cbd), X(0x35d684a6), X(0x74208150), + X(0x36041ad9), X(0x740b53fb), X(0x3631a8b8), X(0x73f614c0), + X(0x365f2e3b), X(0x73e0c3a3), X(0x368cab5c), X(0x73cb60a8), + X(0x36ba2014), X(0x73b5ebd1), X(0x36e78c5b), X(0x73a06522), + X(0x3714f02a), X(0x738acc9e), X(0x37424b7b), X(0x73752249), + X(0x376f9e46), X(0x735f6626), X(0x379ce885), X(0x73499838), + X(0x37ca2a30), X(0x7333b883), X(0x37f76341), X(0x731dc70a), + X(0x382493b0), X(0x7307c3d0), X(0x3851bb77), X(0x72f1aed9), + X(0x387eda8e), X(0x72db8828), X(0x38abf0ef), X(0x72c54fc1), + X(0x38d8fe93), X(0x72af05a7), X(0x39060373), X(0x7298a9dd), + X(0x3932ff87), X(0x72823c67), X(0x395ff2c9), X(0x726bbd48), + X(0x398cdd32), X(0x72552c85), X(0x39b9bebc), X(0x723e8a20), + X(0x39e6975e), X(0x7227d61c), X(0x3a136712), X(0x7211107e), + X(0x3a402dd2), X(0x71fa3949), X(0x3a6ceb96), X(0x71e35080), + X(0x3a99a057), X(0x71cc5626), X(0x3ac64c0f), X(0x71b54a41), + X(0x3af2eeb7), X(0x719e2cd2), X(0x3b1f8848), X(0x7186fdde), + X(0x3b4c18ba), X(0x716fbd68), X(0x3b78a007), X(0x71586b74), + X(0x3ba51e29), X(0x71410805), X(0x3bd19318), X(0x7129931f), + X(0x3bfdfecd), X(0x71120cc5), X(0x3c2a6142), X(0x70fa74fc), + X(0x3c56ba70), X(0x70e2cbc6), X(0x3c830a50), X(0x70cb1128), + X(0x3caf50da), X(0x70b34525), X(0x3cdb8e09), X(0x709b67c0), + X(0x3d07c1d6), X(0x708378ff), X(0x3d33ec39), X(0x706b78e3), + X(0x3d600d2c), X(0x70536771), X(0x3d8c24a8), X(0x703b44ad), + X(0x3db832a6), X(0x7023109a), X(0x3de4371f), X(0x700acb3c), + X(0x3e10320d), X(0x6ff27497), X(0x3e3c2369), X(0x6fda0cae), + X(0x3e680b2c), X(0x6fc19385), X(0x3e93e950), X(0x6fa90921), + X(0x3ebfbdcd), X(0x6f906d84), X(0x3eeb889c), X(0x6f77c0b3), + X(0x3f1749b8), X(0x6f5f02b2), X(0x3f430119), X(0x6f463383), + X(0x3f6eaeb8), X(0x6f2d532c), X(0x3f9a5290), X(0x6f1461b0), + X(0x3fc5ec98), X(0x6efb5f12), X(0x3ff17cca), X(0x6ee24b57), + X(0x401d0321), X(0x6ec92683), X(0x40487f94), X(0x6eaff099), + X(0x4073f21d), X(0x6e96a99d), X(0x409f5ab6), X(0x6e7d5193), + X(0x40cab958), X(0x6e63e87f), X(0x40f60dfb), X(0x6e4a6e66), + X(0x4121589b), X(0x6e30e34a), X(0x414c992f), X(0x6e174730), + X(0x4177cfb1), X(0x6dfd9a1c), X(0x41a2fc1a), X(0x6de3dc11), + X(0x41ce1e65), X(0x6dca0d14), X(0x41f93689), X(0x6db02d29), + X(0x42244481), X(0x6d963c54), X(0x424f4845), X(0x6d7c3a98), + X(0x427a41d0), X(0x6d6227fa), X(0x42a5311b), X(0x6d48047e), + X(0x42d0161e), X(0x6d2dd027), X(0x42faf0d4), X(0x6d138afb), + X(0x4325c135), X(0x6cf934fc), X(0x4350873c), X(0x6cdece2f), + X(0x437b42e1), X(0x6cc45698), X(0x43a5f41e), X(0x6ca9ce3b), + X(0x43d09aed), X(0x6c8f351c), X(0x43fb3746), X(0x6c748b3f), + X(0x4425c923), X(0x6c59d0a9), X(0x4450507e), X(0x6c3f055d), + X(0x447acd50), X(0x6c242960), X(0x44a53f93), X(0x6c093cb6), + X(0x44cfa740), X(0x6bee3f62), X(0x44fa0450), X(0x6bd3316a), + X(0x452456bd), X(0x6bb812d1), X(0x454e9e80), X(0x6b9ce39b), + X(0x4578db93), X(0x6b81a3cd), X(0x45a30df0), X(0x6b66536b), + X(0x45cd358f), X(0x6b4af279), X(0x45f7526b), X(0x6b2f80fb), + X(0x4621647d), X(0x6b13fef5), X(0x464b6bbe), X(0x6af86c6c), + X(0x46756828), X(0x6adcc964), X(0x469f59b4), X(0x6ac115e2), + X(0x46c9405c), X(0x6aa551e9), X(0x46f31c1a), X(0x6a897d7d), + X(0x471cece7), X(0x6a6d98a4), X(0x4746b2bc), X(0x6a51a361), + X(0x47706d93), X(0x6a359db9), X(0x479a1d67), X(0x6a1987b0), + X(0x47c3c22f), X(0x69fd614a), X(0x47ed5be6), X(0x69e12a8c), + X(0x4816ea86), X(0x69c4e37a), X(0x48406e08), X(0x69a88c19), + X(0x4869e665), X(0x698c246c), X(0x48935397), X(0x696fac78), + X(0x48bcb599), X(0x69532442), X(0x48e60c62), X(0x69368bce), + X(0x490f57ee), X(0x6919e320), X(0x49389836), X(0x68fd2a3d), + X(0x4961cd33), X(0x68e06129), X(0x498af6df), X(0x68c387e9), + X(0x49b41533), X(0x68a69e81), X(0x49dd282a), X(0x6889a4f6), + X(0x4a062fbd), X(0x686c9b4b), X(0x4a2f2be6), X(0x684f8186), + X(0x4a581c9e), X(0x683257ab), X(0x4a8101de), X(0x68151dbe), + X(0x4aa9dba2), X(0x67f7d3c5), X(0x4ad2a9e2), X(0x67da79c3), + X(0x4afb6c98), X(0x67bd0fbd), X(0x4b2423be), X(0x679f95b7), + X(0x4b4ccf4d), X(0x67820bb7), X(0x4b756f40), X(0x676471c0), + X(0x4b9e0390), X(0x6746c7d8), X(0x4bc68c36), X(0x67290e02), + X(0x4bef092d), X(0x670b4444), X(0x4c177a6e), X(0x66ed6aa1), + X(0x4c3fdff4), X(0x66cf8120), X(0x4c6839b7), X(0x66b187c3), + X(0x4c9087b1), X(0x66937e91), X(0x4cb8c9dd), X(0x6675658c), + X(0x4ce10034), X(0x66573cbb), X(0x4d092ab0), X(0x66390422), + X(0x4d31494b), X(0x661abbc5), X(0x4d595bfe), X(0x65fc63a9), + X(0x4d8162c4), X(0x65ddfbd3), X(0x4da95d96), X(0x65bf8447), + X(0x4dd14c6e), X(0x65a0fd0b), X(0x4df92f46), X(0x65826622), + X(0x4e210617), X(0x6563bf92), X(0x4e48d0dd), X(0x6545095f), + X(0x4e708f8f), X(0x6526438f), X(0x4e984229), X(0x65076e25), + X(0x4ebfe8a5), X(0x64e88926), X(0x4ee782fb), X(0x64c99498), + X(0x4f0f1126), X(0x64aa907f), X(0x4f369320), X(0x648b7ce0), + X(0x4f5e08e3), X(0x646c59bf), X(0x4f857269), X(0x644d2722), + X(0x4faccfab), X(0x642de50d), X(0x4fd420a4), X(0x640e9386), + X(0x4ffb654d), X(0x63ef3290), X(0x50229da1), X(0x63cfc231), + X(0x5049c999), X(0x63b0426d), X(0x5070e92f), X(0x6390b34a), + X(0x5097fc5e), X(0x637114cc), X(0x50bf031f), X(0x635166f9), + X(0x50e5fd6d), X(0x6331a9d4), X(0x510ceb40), X(0x6311dd64), + X(0x5133cc94), X(0x62f201ac), X(0x515aa162), X(0x62d216b3), + X(0x518169a5), X(0x62b21c7b), X(0x51a82555), X(0x6292130c), + X(0x51ced46e), X(0x6271fa69), X(0x51f576ea), X(0x6251d298), + X(0x521c0cc2), X(0x62319b9d), X(0x524295f0), X(0x6211557e), + X(0x5269126e), X(0x61f1003f), X(0x528f8238), X(0x61d09be5), + X(0x52b5e546), X(0x61b02876), X(0x52dc3b92), X(0x618fa5f7), + X(0x53028518), X(0x616f146c), X(0x5328c1d0), X(0x614e73da), + X(0x534ef1b5), X(0x612dc447), X(0x537514c2), X(0x610d05b7), + X(0x539b2af0), X(0x60ec3830), X(0x53c13439), X(0x60cb5bb7), + X(0x53e73097), X(0x60aa7050), X(0x540d2005), X(0x60897601), + X(0x5433027d), X(0x60686ccf), X(0x5458d7f9), X(0x604754bf), + X(0x547ea073), X(0x60262dd6), X(0x54a45be6), X(0x6004f819), + X(0x54ca0a4b), X(0x5fe3b38d), X(0x54efab9c), X(0x5fc26038), + X(0x55153fd4), X(0x5fa0fe1f), X(0x553ac6ee), X(0x5f7f8d46), + X(0x556040e2), X(0x5f5e0db3), X(0x5585adad), X(0x5f3c7f6b), + X(0x55ab0d46), X(0x5f1ae274), X(0x55d05faa), X(0x5ef936d1), + X(0x55f5a4d2), X(0x5ed77c8a), X(0x561adcb9), X(0x5eb5b3a2), + X(0x56400758), X(0x5e93dc1f), X(0x566524aa), X(0x5e71f606), + X(0x568a34a9), X(0x5e50015d), X(0x56af3750), X(0x5e2dfe29), + X(0x56d42c99), X(0x5e0bec6e), X(0x56f9147e), X(0x5de9cc33), + X(0x571deefa), X(0x5dc79d7c), X(0x5742bc06), X(0x5da5604f), + X(0x57677b9d), X(0x5d8314b1), X(0x578c2dba), X(0x5d60baa7), + X(0x57b0d256), X(0x5d3e5237), X(0x57d5696d), X(0x5d1bdb65), + X(0x57f9f2f8), X(0x5cf95638), X(0x581e6ef1), X(0x5cd6c2b5), + X(0x5842dd54), X(0x5cb420e0), X(0x58673e1b), X(0x5c9170bf), + X(0x588b9140), X(0x5c6eb258), X(0x58afd6bd), X(0x5c4be5b0), + X(0x58d40e8c), X(0x5c290acc), X(0x58f838a9), X(0x5c0621b2), + X(0x591c550e), X(0x5be32a67), X(0x594063b5), X(0x5bc024f0), + X(0x59646498), X(0x5b9d1154), X(0x598857b2), X(0x5b79ef96), + X(0x59ac3cfd), X(0x5b56bfbd), X(0x59d01475), X(0x5b3381ce), + X(0x59f3de12), X(0x5b1035cf), X(0x5a1799d1), X(0x5aecdbc5), + X(0x5a3b47ab), X(0x5ac973b5), X(0x5a5ee79a), X(0x5aa5fda5), + X(0x5a82799a), X(0x5a82799a) + }; + + /* {sin((2*i+1)*PI/4096), cos((2*i+1)*PI/4096)}, with i = 0 to 511 */ +static LOOKUP_T sincos_lookup1[1024] = { + X(0x001921fb), X(0x7ffffd88), X(0x004b65ee), X(0x7fffe9cb), + X(0x007da9d4), X(0x7fffc251), X(0x00afeda8), X(0x7fff8719), + X(0x00e23160), X(0x7fff3824), X(0x011474f6), X(0x7ffed572), + X(0x0146b860), X(0x7ffe5f03), X(0x0178fb99), X(0x7ffdd4d7), + X(0x01ab3e97), X(0x7ffd36ee), X(0x01dd8154), X(0x7ffc8549), + X(0x020fc3c6), X(0x7ffbbfe6), X(0x024205e8), X(0x7ffae6c7), + X(0x027447b0), X(0x7ff9f9ec), X(0x02a68917), X(0x7ff8f954), + X(0x02d8ca16), X(0x7ff7e500), X(0x030b0aa4), X(0x7ff6bcf0), + X(0x033d4abb), X(0x7ff58125), X(0x036f8a51), X(0x7ff4319d), + X(0x03a1c960), X(0x7ff2ce5b), X(0x03d407df), X(0x7ff1575d), + X(0x040645c7), X(0x7fefcca4), X(0x04388310), X(0x7fee2e30), + X(0x046abfb3), X(0x7fec7c02), X(0x049cfba7), X(0x7feab61a), + X(0x04cf36e5), X(0x7fe8dc78), X(0x05017165), X(0x7fe6ef1c), + X(0x0533ab20), X(0x7fe4ee06), X(0x0565e40d), X(0x7fe2d938), + X(0x05981c26), X(0x7fe0b0b1), X(0x05ca5361), X(0x7fde7471), + X(0x05fc89b8), X(0x7fdc247a), X(0x062ebf22), X(0x7fd9c0ca), + X(0x0660f398), X(0x7fd74964), X(0x06932713), X(0x7fd4be46), + X(0x06c5598a), X(0x7fd21f72), X(0x06f78af6), X(0x7fcf6ce8), + X(0x0729bb4e), X(0x7fcca6a7), X(0x075bea8c), X(0x7fc9ccb2), + X(0x078e18a7), X(0x7fc6df08), X(0x07c04598), X(0x7fc3dda9), + X(0x07f27157), X(0x7fc0c896), X(0x08249bdd), X(0x7fbd9fd0), + X(0x0856c520), X(0x7fba6357), X(0x0888ed1b), X(0x7fb7132b), + X(0x08bb13c5), X(0x7fb3af4e), X(0x08ed3916), X(0x7fb037bf), + X(0x091f5d06), X(0x7facac7f), X(0x09517f8f), X(0x7fa90d8e), + X(0x0983a0a7), X(0x7fa55aee), X(0x09b5c048), X(0x7fa1949e), + X(0x09e7de6a), X(0x7f9dbaa0), X(0x0a19fb04), X(0x7f99ccf4), + X(0x0a4c1610), X(0x7f95cb9a), X(0x0a7e2f85), X(0x7f91b694), + X(0x0ab0475c), X(0x7f8d8de1), X(0x0ae25d8d), X(0x7f895182), + X(0x0b147211), X(0x7f850179), X(0x0b4684df), X(0x7f809dc5), + X(0x0b7895f0), X(0x7f7c2668), X(0x0baaa53b), X(0x7f779b62), + X(0x0bdcb2bb), X(0x7f72fcb4), X(0x0c0ebe66), X(0x7f6e4a5e), + X(0x0c40c835), X(0x7f698461), X(0x0c72d020), X(0x7f64aabf), + X(0x0ca4d620), X(0x7f5fbd77), X(0x0cd6da2d), X(0x7f5abc8a), + X(0x0d08dc3f), X(0x7f55a7fa), X(0x0d3adc4e), X(0x7f507fc7), + X(0x0d6cda53), X(0x7f4b43f2), X(0x0d9ed646), X(0x7f45f47b), + X(0x0dd0d01f), X(0x7f409164), X(0x0e02c7d7), X(0x7f3b1aad), + X(0x0e34bd66), X(0x7f359057), X(0x0e66b0c3), X(0x7f2ff263), + X(0x0e98a1e9), X(0x7f2a40d2), X(0x0eca90ce), X(0x7f247ba5), + X(0x0efc7d6b), X(0x7f1ea2dc), X(0x0f2e67b8), X(0x7f18b679), + X(0x0f604faf), X(0x7f12b67c), X(0x0f923546), X(0x7f0ca2e7), + X(0x0fc41876), X(0x7f067bba), X(0x0ff5f938), X(0x7f0040f6), + X(0x1027d784), X(0x7ef9f29d), X(0x1059b352), X(0x7ef390ae), + X(0x108b8c9b), X(0x7eed1b2c), X(0x10bd6356), X(0x7ee69217), + X(0x10ef377d), X(0x7edff570), X(0x11210907), X(0x7ed94538), + X(0x1152d7ed), X(0x7ed28171), X(0x1184a427), X(0x7ecbaa1a), + X(0x11b66dad), X(0x7ec4bf36), X(0x11e83478), X(0x7ebdc0c6), + X(0x1219f880), X(0x7eb6aeca), X(0x124bb9be), X(0x7eaf8943), + X(0x127d7829), X(0x7ea85033), X(0x12af33ba), X(0x7ea1039b), + X(0x12e0ec6a), X(0x7e99a37c), X(0x1312a230), X(0x7e922fd6), + X(0x13445505), X(0x7e8aa8ac), X(0x137604e2), X(0x7e830dff), + X(0x13a7b1bf), X(0x7e7b5fce), X(0x13d95b93), X(0x7e739e1d), + X(0x140b0258), X(0x7e6bc8eb), X(0x143ca605), X(0x7e63e03b), + X(0x146e4694), X(0x7e5be40c), X(0x149fe3fc), X(0x7e53d462), + X(0x14d17e36), X(0x7e4bb13c), X(0x1503153a), X(0x7e437a9c), + X(0x1534a901), X(0x7e3b3083), X(0x15663982), X(0x7e32d2f4), + X(0x1597c6b7), X(0x7e2a61ed), X(0x15c95097), X(0x7e21dd73), + X(0x15fad71b), X(0x7e194584), X(0x162c5a3b), X(0x7e109a24), + X(0x165dd9f0), X(0x7e07db52), X(0x168f5632), X(0x7dff0911), + X(0x16c0cef9), X(0x7df62362), X(0x16f2443e), X(0x7ded2a47), + X(0x1723b5f9), X(0x7de41dc0), X(0x17552422), X(0x7ddafdce), + X(0x17868eb3), X(0x7dd1ca75), X(0x17b7f5a3), X(0x7dc883b4), + X(0x17e958ea), X(0x7dbf298d), X(0x181ab881), X(0x7db5bc02), + X(0x184c1461), X(0x7dac3b15), X(0x187d6c82), X(0x7da2a6c6), + X(0x18aec0db), X(0x7d98ff17), X(0x18e01167), X(0x7d8f4409), + X(0x19115e1c), X(0x7d85759f), X(0x1942a6f3), X(0x7d7b93da), + X(0x1973ebe6), X(0x7d719eba), X(0x19a52ceb), X(0x7d679642), + X(0x19d669fc), X(0x7d5d7a74), X(0x1a07a311), X(0x7d534b50), + X(0x1a38d823), X(0x7d4908d9), X(0x1a6a0929), X(0x7d3eb30f), + X(0x1a9b361d), X(0x7d3449f5), X(0x1acc5ef6), X(0x7d29cd8c), + X(0x1afd83ad), X(0x7d1f3dd6), X(0x1b2ea43a), X(0x7d149ad5), + X(0x1b5fc097), X(0x7d09e489), X(0x1b90d8bb), X(0x7cff1af5), + X(0x1bc1ec9e), X(0x7cf43e1a), X(0x1bf2fc3a), X(0x7ce94dfb), + X(0x1c240786), X(0x7cde4a98), X(0x1c550e7c), X(0x7cd333f3), + X(0x1c861113), X(0x7cc80a0f), X(0x1cb70f43), X(0x7cbcccec), + X(0x1ce80906), X(0x7cb17c8d), X(0x1d18fe54), X(0x7ca618f3), + X(0x1d49ef26), X(0x7c9aa221), X(0x1d7adb73), X(0x7c8f1817), + X(0x1dabc334), X(0x7c837ad8), X(0x1ddca662), X(0x7c77ca65), + X(0x1e0d84f5), X(0x7c6c06c0), X(0x1e3e5ee5), X(0x7c602fec), + X(0x1e6f342c), X(0x7c5445e9), X(0x1ea004c1), X(0x7c4848ba), + X(0x1ed0d09d), X(0x7c3c3860), X(0x1f0197b8), X(0x7c3014de), + X(0x1f325a0b), X(0x7c23de35), X(0x1f63178f), X(0x7c179467), + X(0x1f93d03c), X(0x7c0b3777), X(0x1fc4840a), X(0x7bfec765), + X(0x1ff532f2), X(0x7bf24434), X(0x2025dcec), X(0x7be5ade6), + X(0x205681f1), X(0x7bd9047c), X(0x208721f9), X(0x7bcc47fa), + X(0x20b7bcfe), X(0x7bbf7860), X(0x20e852f6), X(0x7bb295b0), + X(0x2118e3dc), X(0x7ba59fee), X(0x21496fa7), X(0x7b989719), + X(0x2179f64f), X(0x7b8b7b36), X(0x21aa77cf), X(0x7b7e4c45), + X(0x21daf41d), X(0x7b710a49), X(0x220b6b32), X(0x7b63b543), + X(0x223bdd08), X(0x7b564d36), X(0x226c4996), X(0x7b48d225), + X(0x229cb0d5), X(0x7b3b4410), X(0x22cd12bd), X(0x7b2da2fa), + X(0x22fd6f48), X(0x7b1feee5), X(0x232dc66d), X(0x7b1227d3), + X(0x235e1826), X(0x7b044dc7), X(0x238e646a), X(0x7af660c2), + X(0x23beab33), X(0x7ae860c7), X(0x23eeec78), X(0x7ada4dd8), + X(0x241f2833), X(0x7acc27f7), X(0x244f5e5c), X(0x7abdef25), + X(0x247f8eec), X(0x7aafa367), X(0x24afb9da), X(0x7aa144bc), + X(0x24dfdf20), X(0x7a92d329), X(0x250ffeb7), X(0x7a844eae), + X(0x25401896), X(0x7a75b74f), X(0x25702cb7), X(0x7a670d0d), + X(0x25a03b11), X(0x7a584feb), X(0x25d0439f), X(0x7a497feb), + X(0x26004657), X(0x7a3a9d0f), X(0x26304333), X(0x7a2ba75a), + X(0x26603a2c), X(0x7a1c9ece), X(0x26902b39), X(0x7a0d836d), + X(0x26c01655), X(0x79fe5539), X(0x26effb76), X(0x79ef1436), + X(0x271fda96), X(0x79dfc064), X(0x274fb3ae), X(0x79d059c8), + X(0x277f86b5), X(0x79c0e062), X(0x27af53a6), X(0x79b15435), + X(0x27df1a77), X(0x79a1b545), X(0x280edb23), X(0x79920392), + X(0x283e95a1), X(0x79823f20), X(0x286e49ea), X(0x797267f2), + X(0x289df7f8), X(0x79627e08), X(0x28cd9fc1), X(0x79528167), + X(0x28fd4140), X(0x79427210), X(0x292cdc6d), X(0x79325006), + X(0x295c7140), X(0x79221b4b), X(0x298bffb2), X(0x7911d3e2), + X(0x29bb87bc), X(0x790179cd), X(0x29eb0957), X(0x78f10d0f), + X(0x2a1a847b), X(0x78e08dab), X(0x2a49f920), X(0x78cffba3), + X(0x2a796740), X(0x78bf56f9), X(0x2aa8ced3), X(0x78ae9fb0), + X(0x2ad82fd2), X(0x789dd5cb), X(0x2b078a36), X(0x788cf94c), + X(0x2b36ddf7), X(0x787c0a36), X(0x2b662b0e), X(0x786b088c), + X(0x2b957173), X(0x7859f44f), X(0x2bc4b120), X(0x7848cd83), + X(0x2bf3ea0d), X(0x7837942b), X(0x2c231c33), X(0x78264849), + X(0x2c52478a), X(0x7814e9df), X(0x2c816c0c), X(0x780378f1), + X(0x2cb089b1), X(0x77f1f581), X(0x2cdfa071), X(0x77e05f91), + X(0x2d0eb046), X(0x77ceb725), X(0x2d3db928), X(0x77bcfc3f), + X(0x2d6cbb10), X(0x77ab2ee2), X(0x2d9bb5f6), X(0x77994f11), + X(0x2dcaa9d5), X(0x77875cce), X(0x2df996a3), X(0x7775581d), + X(0x2e287c5a), X(0x776340ff), X(0x2e575af3), X(0x77511778), + X(0x2e863267), X(0x773edb8b), X(0x2eb502ae), X(0x772c8d3a), + X(0x2ee3cbc1), X(0x771a2c88), X(0x2f128d99), X(0x7707b979), + X(0x2f41482e), X(0x76f5340e), X(0x2f6ffb7a), X(0x76e29c4b), + X(0x2f9ea775), X(0x76cff232), X(0x2fcd4c19), X(0x76bd35c7), + X(0x2ffbe95d), X(0x76aa670d), X(0x302a7f3a), X(0x76978605), + X(0x30590dab), X(0x768492b4), X(0x308794a6), X(0x76718d1c), + X(0x30b61426), X(0x765e7540), X(0x30e48c22), X(0x764b4b23), + X(0x3112fc95), X(0x76380ec8), X(0x31416576), X(0x7624c031), + X(0x316fc6be), X(0x76115f63), X(0x319e2067), X(0x75fdec60), + X(0x31cc7269), X(0x75ea672a), X(0x31fabcbd), X(0x75d6cfc5), + X(0x3228ff5c), X(0x75c32634), X(0x32573a3f), X(0x75af6a7b), + X(0x32856d5e), X(0x759b9c9b), X(0x32b398b3), X(0x7587bc98), + X(0x32e1bc36), X(0x7573ca75), X(0x330fd7e1), X(0x755fc635), + X(0x333debab), X(0x754bafdc), X(0x336bf78f), X(0x7537876c), + X(0x3399fb85), X(0x75234ce8), X(0x33c7f785), X(0x750f0054), + X(0x33f5eb89), X(0x74faa1b3), X(0x3423d78a), X(0x74e63108), + X(0x3451bb81), X(0x74d1ae55), X(0x347f9766), X(0x74bd199f), + X(0x34ad6b32), X(0x74a872e8), X(0x34db36df), X(0x7493ba34), + X(0x3508fa66), X(0x747eef85), X(0x3536b5be), X(0x746a12df), + X(0x356468e2), X(0x74552446), X(0x359213c9), X(0x744023bc), + X(0x35bfb66e), X(0x742b1144), X(0x35ed50c9), X(0x7415ece2), + X(0x361ae2d3), X(0x7400b69a), X(0x36486c86), X(0x73eb6e6e), + X(0x3675edd9), X(0x73d61461), X(0x36a366c6), X(0x73c0a878), + X(0x36d0d746), X(0x73ab2ab4), X(0x36fe3f52), X(0x73959b1b), + X(0x372b9ee3), X(0x737ff9ae), X(0x3758f5f2), X(0x736a4671), + X(0x37864477), X(0x73548168), X(0x37b38a6d), X(0x733eaa96), + X(0x37e0c7cc), X(0x7328c1ff), X(0x380dfc8d), X(0x7312c7a5), + X(0x383b28a9), X(0x72fcbb8c), X(0x38684c19), X(0x72e69db7), + X(0x389566d6), X(0x72d06e2b), X(0x38c278d9), X(0x72ba2cea), + X(0x38ef821c), X(0x72a3d9f7), X(0x391c8297), X(0x728d7557), + X(0x39497a43), X(0x7276ff0d), X(0x39766919), X(0x7260771b), + X(0x39a34f13), X(0x7249dd86), X(0x39d02c2a), X(0x72333251), + X(0x39fd0056), X(0x721c7580), X(0x3a29cb91), X(0x7205a716), + X(0x3a568dd4), X(0x71eec716), X(0x3a834717), X(0x71d7d585), + X(0x3aaff755), X(0x71c0d265), X(0x3adc9e86), X(0x71a9bdba), + X(0x3b093ca3), X(0x71929789), X(0x3b35d1a5), X(0x717b5fd3), + X(0x3b625d86), X(0x7164169d), X(0x3b8ee03e), X(0x714cbbeb), + X(0x3bbb59c7), X(0x71354fc0), X(0x3be7ca1a), X(0x711dd220), + X(0x3c143130), X(0x7106430e), X(0x3c408f03), X(0x70eea28e), + X(0x3c6ce38a), X(0x70d6f0a4), X(0x3c992ec0), X(0x70bf2d53), + X(0x3cc5709e), X(0x70a7589f), X(0x3cf1a91c), X(0x708f728b), + X(0x3d1dd835), X(0x70777b1c), X(0x3d49fde1), X(0x705f7255), + X(0x3d761a19), X(0x70475839), X(0x3da22cd7), X(0x702f2ccd), + X(0x3dce3614), X(0x7016f014), X(0x3dfa35c8), X(0x6ffea212), + X(0x3e262bee), X(0x6fe642ca), X(0x3e52187f), X(0x6fcdd241), + X(0x3e7dfb73), X(0x6fb5507a), X(0x3ea9d4c3), X(0x6f9cbd79), + X(0x3ed5a46b), X(0x6f841942), X(0x3f016a61), X(0x6f6b63d8), + X(0x3f2d26a0), X(0x6f529d40), X(0x3f58d921), X(0x6f39c57d), + X(0x3f8481dd), X(0x6f20dc92), X(0x3fb020ce), X(0x6f07e285), + X(0x3fdbb5ec), X(0x6eeed758), X(0x40074132), X(0x6ed5bb10), + X(0x4032c297), X(0x6ebc8db0), X(0x405e3a16), X(0x6ea34f3d), + X(0x4089a7a8), X(0x6e89ffb9), X(0x40b50b46), X(0x6e709f2a), + X(0x40e064ea), X(0x6e572d93), X(0x410bb48c), X(0x6e3daaf8), + X(0x4136fa27), X(0x6e24175c), X(0x416235b2), X(0x6e0a72c5), + X(0x418d6729), X(0x6df0bd35), X(0x41b88e84), X(0x6dd6f6b1), + X(0x41e3abbc), X(0x6dbd1f3c), X(0x420ebecb), X(0x6da336dc), + X(0x4239c7aa), X(0x6d893d93), X(0x4264c653), X(0x6d6f3365), + X(0x428fbabe), X(0x6d551858), X(0x42baa4e6), X(0x6d3aec6e), + X(0x42e584c3), X(0x6d20afac), X(0x43105a50), X(0x6d066215), + X(0x433b2585), X(0x6cec03af), X(0x4365e65b), X(0x6cd1947c), + X(0x43909ccd), X(0x6cb71482), X(0x43bb48d4), X(0x6c9c83c3), + X(0x43e5ea68), X(0x6c81e245), X(0x44108184), X(0x6c67300b), + X(0x443b0e21), X(0x6c4c6d1a), X(0x44659039), X(0x6c319975), + X(0x449007c4), X(0x6c16b521), X(0x44ba74bd), X(0x6bfbc021), + X(0x44e4d71c), X(0x6be0ba7b), X(0x450f2edb), X(0x6bc5a431), + X(0x45397bf4), X(0x6baa7d49), X(0x4563be60), X(0x6b8f45c7), + X(0x458df619), X(0x6b73fdae), X(0x45b82318), X(0x6b58a503), + X(0x45e24556), X(0x6b3d3bcb), X(0x460c5cce), X(0x6b21c208), + X(0x46366978), X(0x6b0637c1), X(0x46606b4e), X(0x6aea9cf8), + X(0x468a624a), X(0x6acef1b2), X(0x46b44e65), X(0x6ab335f4), + X(0x46de2f99), X(0x6a9769c1), X(0x470805df), X(0x6a7b8d1e), + X(0x4731d131), X(0x6a5fa010), X(0x475b9188), X(0x6a43a29a), + X(0x478546de), X(0x6a2794c1), X(0x47aef12c), X(0x6a0b7689), + X(0x47d8906d), X(0x69ef47f6), X(0x48022499), X(0x69d3090e), + X(0x482badab), X(0x69b6b9d3), X(0x48552b9b), X(0x699a5a4c), + X(0x487e9e64), X(0x697dea7b), X(0x48a805ff), X(0x69616a65), + X(0x48d16265), X(0x6944da10), X(0x48fab391), X(0x6928397e), + X(0x4923f97b), X(0x690b88b5), X(0x494d341e), X(0x68eec7b9), + X(0x49766373), X(0x68d1f68f), X(0x499f8774), X(0x68b5153a), + X(0x49c8a01b), X(0x689823bf), X(0x49f1ad61), X(0x687b2224), + X(0x4a1aaf3f), X(0x685e106c), X(0x4a43a5b0), X(0x6840ee9b), + X(0x4a6c90ad), X(0x6823bcb7), X(0x4a957030), X(0x68067ac3), + X(0x4abe4433), X(0x67e928c5), X(0x4ae70caf), X(0x67cbc6c0), + X(0x4b0fc99d), X(0x67ae54ba), X(0x4b387af9), X(0x6790d2b6), + X(0x4b6120bb), X(0x677340ba), X(0x4b89badd), X(0x67559eca), + X(0x4bb24958), X(0x6737ecea), X(0x4bdacc28), X(0x671a2b20), + X(0x4c034345), X(0x66fc596f), X(0x4c2baea9), X(0x66de77dc), + X(0x4c540e4e), X(0x66c0866d), X(0x4c7c622d), X(0x66a28524), + X(0x4ca4aa41), X(0x66847408), X(0x4ccce684), X(0x6666531d), + X(0x4cf516ee), X(0x66482267), X(0x4d1d3b7a), X(0x6629e1ec), + X(0x4d455422), X(0x660b91af), X(0x4d6d60df), X(0x65ed31b5), + X(0x4d9561ac), X(0x65cec204), X(0x4dbd5682), X(0x65b0429f), + X(0x4de53f5a), X(0x6591b38c), X(0x4e0d1c30), X(0x657314cf), + X(0x4e34ecfc), X(0x6554666d), X(0x4e5cb1b9), X(0x6535a86b), + X(0x4e846a60), X(0x6516dacd), X(0x4eac16eb), X(0x64f7fd98), + X(0x4ed3b755), X(0x64d910d1), X(0x4efb4b96), X(0x64ba147d), + X(0x4f22d3aa), X(0x649b08a0), X(0x4f4a4f89), X(0x647bed3f), + X(0x4f71bf2e), X(0x645cc260), X(0x4f992293), X(0x643d8806), + X(0x4fc079b1), X(0x641e3e38), X(0x4fe7c483), X(0x63fee4f8), + X(0x500f0302), X(0x63df7c4d), X(0x50363529), X(0x63c0043b), + X(0x505d5af1), X(0x63a07cc7), X(0x50847454), X(0x6380e5f6), + X(0x50ab814d), X(0x63613fcd), X(0x50d281d5), X(0x63418a50), + X(0x50f975e6), X(0x6321c585), X(0x51205d7b), X(0x6301f171), + X(0x5147388c), X(0x62e20e17), X(0x516e0715), X(0x62c21b7e), + X(0x5194c910), X(0x62a219aa), X(0x51bb7e75), X(0x628208a1), + X(0x51e22740), X(0x6261e866), X(0x5208c36a), X(0x6241b8ff), + X(0x522f52ee), X(0x62217a72), X(0x5255d5c5), X(0x62012cc2), + X(0x527c4bea), X(0x61e0cff5), X(0x52a2b556), X(0x61c06410), + X(0x52c91204), X(0x619fe918), X(0x52ef61ee), X(0x617f5f12), + X(0x5315a50e), X(0x615ec603), X(0x533bdb5d), X(0x613e1df0), + X(0x536204d7), X(0x611d66de), X(0x53882175), X(0x60fca0d2), + X(0x53ae3131), X(0x60dbcbd1), X(0x53d43406), X(0x60bae7e1), + X(0x53fa29ed), X(0x6099f505), X(0x542012e1), X(0x6078f344), + X(0x5445eedb), X(0x6057e2a2), X(0x546bbdd7), X(0x6036c325), + X(0x54917fce), X(0x601594d1), X(0x54b734ba), X(0x5ff457ad), + X(0x54dcdc96), X(0x5fd30bbc), X(0x5502775c), X(0x5fb1b104), + X(0x55280505), X(0x5f90478a), X(0x554d858d), X(0x5f6ecf53), + X(0x5572f8ed), X(0x5f4d4865), X(0x55985f20), X(0x5f2bb2c5), + X(0x55bdb81f), X(0x5f0a0e77), X(0x55e303e6), X(0x5ee85b82), + X(0x5608426e), X(0x5ec699e9), X(0x562d73b2), X(0x5ea4c9b3), + X(0x565297ab), X(0x5e82eae5), X(0x5677ae54), X(0x5e60fd84), + X(0x569cb7a8), X(0x5e3f0194), X(0x56c1b3a1), X(0x5e1cf71c), + X(0x56e6a239), X(0x5dfade20), X(0x570b8369), X(0x5dd8b6a7), + X(0x5730572e), X(0x5db680b4), X(0x57551d80), X(0x5d943c4e), + X(0x5779d65b), X(0x5d71e979), X(0x579e81b8), X(0x5d4f883b), + X(0x57c31f92), X(0x5d2d189a), X(0x57e7afe4), X(0x5d0a9a9a), + X(0x580c32a7), X(0x5ce80e41), X(0x5830a7d6), X(0x5cc57394), + X(0x58550f6c), X(0x5ca2ca99), X(0x58796962), X(0x5c801354), + X(0x589db5b3), X(0x5c5d4dcc), X(0x58c1f45b), X(0x5c3a7a05), + X(0x58e62552), X(0x5c179806), X(0x590a4893), X(0x5bf4a7d2), + X(0x592e5e19), X(0x5bd1a971), X(0x595265df), X(0x5bae9ce7), + X(0x59765fde), X(0x5b8b8239), X(0x599a4c12), X(0x5b68596d), + X(0x59be2a74), X(0x5b452288), X(0x59e1faff), X(0x5b21dd90), + X(0x5a05bdae), X(0x5afe8a8b), X(0x5a29727b), X(0x5adb297d), + X(0x5a4d1960), X(0x5ab7ba6c), X(0x5a70b258), X(0x5a943d5e), +}; + diff --git a/genplus-gx/core/tremor/misc.h b/genplus-gx/core/tremor/misc.h new file mode 100644 index 0000000000..12856d97a9 --- /dev/null +++ b/genplus-gx/core/tremor/misc.h @@ -0,0 +1,248 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: miscellaneous math and prototypes + + ********************************************************************/ + +#ifndef _V_RANDOM_H_ +#define _V_RANDOM_H_ +#include "ivorbiscodec.h" +#include "os.h" + +#include "asm_arm.h" +#include /* for abs() */ + +#ifdef GEKKO +#include +#endif + +#ifndef _V_WIDE_MATH +#define _V_WIDE_MATH + +#ifndef _LOW_ACCURACY_ +/* 64 bit multiply */ + +#if !(defined WIN32 && defined WINCE) +#include +#endif + +#if BYTE_ORDER==LITTLE_ENDIAN +union magic { + struct { + ogg_int32_t lo; + ogg_int32_t hi; + } halves; + ogg_int64_t whole; +}; +#endif + +#if BYTE_ORDER==BIG_ENDIAN +union magic { + struct { + ogg_int32_t hi; + ogg_int32_t lo; + } halves; + ogg_int64_t whole; +}; +#endif + +STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { + union magic magic; + magic.whole = (ogg_int64_t)x * y; + return magic.halves.hi; +} + +STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { + return MULT32(x,y)<<1; +} + +STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) { + union magic magic; + magic.whole = (ogg_int64_t)x * y; + return ((ogg_uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17); +} + +#else +/* 32 bit multiply, more portable but less accurate */ + +/* + * Note: Precision is biased towards the first argument therefore ordering + * is important. Shift values were chosen for the best sound quality after + * many listening tests. + */ + +/* + * For MULT32 and MULT31: The second argument is always a lookup table + * value already preshifted from 31 to 8 bits. We therefore take the + * opportunity to save on text space and use unsigned char for those + * tables in this case. + */ + +STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { + return (x >> 9) * y; /* y preshifted >>23 */ +} + +STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { + return (x >> 8) * y; /* y preshifted >>23 */ +} + +STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) { + return (x >> 6) * y; /* y preshifted >>9 */ +} + +#endif + +/* + * This should be used as a memory barrier, forcing all cached values in + * registers to wr writen back to memory. Might or might not be beneficial + * depending on the architecture and compiler. + */ +#define MB() + +/* + * The XPROD functions are meant to optimize the cross products found all + * over the place in mdct.c by forcing memory operation ordering to avoid + * unnecessary register reloads as soon as memory is being written to. + * However this is only beneficial on CPUs with a sane number of general + * purpose registers which exclude the Intel x86. On Intel, better let the + * compiler actually reload registers directly from original memory by using + * macros. + */ + +#ifdef __i386__ + +#define XPROD32(_a, _b, _t, _v, _x, _y) \ + { *(_x)=MULT32(_a,_t)+MULT32(_b,_v); \ + *(_y)=MULT32(_b,_t)-MULT32(_a,_v); } +#define XPROD31(_a, _b, _t, _v, _x, _y) \ + { *(_x)=MULT31(_a,_t)+MULT31(_b,_v); \ + *(_y)=MULT31(_b,_t)-MULT31(_a,_v); } +#define XNPROD31(_a, _b, _t, _v, _x, _y) \ + { *(_x)=MULT31(_a,_t)-MULT31(_b,_v); \ + *(_y)=MULT31(_b,_t)+MULT31(_a,_v); } + +#else + +STIN void XPROD32(ogg_int32_t a, ogg_int32_t b, + ogg_int32_t t, ogg_int32_t v, + ogg_int32_t *x, ogg_int32_t *y) +{ + *x = MULT32(a, t) + MULT32(b, v); + *y = MULT32(b, t) - MULT32(a, v); +} + +STIN void XPROD31(ogg_int32_t a, ogg_int32_t b, + ogg_int32_t t, ogg_int32_t v, + ogg_int32_t *x, ogg_int32_t *y) +{ + *x = MULT31(a, t) + MULT31(b, v); + *y = MULT31(b, t) - MULT31(a, v); +} + +STIN void XNPROD31(ogg_int32_t a, ogg_int32_t b, + ogg_int32_t t, ogg_int32_t v, + ogg_int32_t *x, ogg_int32_t *y) +{ + *x = MULT31(a, t) - MULT31(b, v); + *y = MULT31(b, t) + MULT31(a, v); +} + +#endif + +#endif + +#ifndef _V_CLIP_MATH +#define _V_CLIP_MATH + +STIN ogg_int32_t CLIP_TO_15(ogg_int32_t x) { + int ret=x; + ret-= ((x<=32767)-1)&(x-32767); + ret-= ((x>=-32768)-1)&(x+32768); + return(ret); +} + +#endif + +STIN ogg_int32_t VFLOAT_MULT(ogg_int32_t a,ogg_int32_t ap, + ogg_int32_t b,ogg_int32_t bp, + ogg_int32_t *p){ + if(a && b){ +#ifndef _LOW_ACCURACY_ + *p=ap+bp+32; + return MULT32(a,b); +#else + *p=ap+bp+31; + return (a>>15)*(b>>16); +#endif + }else + return 0; +} + +int _ilog(unsigned int); + +STIN ogg_int32_t VFLOAT_MULTI(ogg_int32_t a,ogg_int32_t ap, + ogg_int32_t i, + ogg_int32_t *p){ + + int ip=_ilog(abs(i))-31; + return VFLOAT_MULT(a,ap,i<<-ip,ip,p); +} + +STIN ogg_int32_t VFLOAT_ADD(ogg_int32_t a,ogg_int32_t ap, + ogg_int32_t b,ogg_int32_t bp, + ogg_int32_t *p){ + + if(!a){ + *p=bp; + return b; + }else if(!b){ + *p=ap; + return a; + } + + /* yes, this can leak a bit. */ + if(ap>bp){ + int shift=ap-bp+1; + *p=ap+1; + a>>=1; + if(shift<32){ + b=(b+(1<<(shift-1)))>>shift; + }else{ + b=0; + } + }else{ + int shift=bp-ap+1; + *p=bp+1; + b>>=1; + if(shift<32){ + a=(a+(1<<(shift-1)))>>shift; + }else{ + a=0; + } + } + + a+=b; + if((a&0xc0000000)==0xc0000000 || + (a&0xc0000000)==0){ + a<<=1; + (*p)--; + } + return(a); +} + +#endif + + + + diff --git a/genplus-gx/core/tremor/ogg.h b/genplus-gx/core/tremor/ogg.h new file mode 100644 index 0000000000..85cb41b64a --- /dev/null +++ b/genplus-gx/core/tremor/ogg.h @@ -0,0 +1,206 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: subsumed libogg includes + + ********************************************************************/ +#ifndef _OGG_H +#define _OGG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "os_types.h" + +typedef struct ogg_buffer_state{ + struct ogg_buffer *unused_buffers; + struct ogg_reference *unused_references; + int outstanding; + int shutdown; +} ogg_buffer_state; + +typedef struct ogg_buffer { + unsigned char *data; + long size; + int refcount; + + union { + ogg_buffer_state *owner; + struct ogg_buffer *next; + } ptr; +} ogg_buffer; + +typedef struct ogg_reference { + ogg_buffer *buffer; + long begin; + long length; + + struct ogg_reference *next; +} ogg_reference; + +typedef struct oggpack_buffer { + int headbit; + unsigned char *headptr; + long headend; + + /* memory management */ + ogg_reference *head; + ogg_reference *tail; + + /* render the byte/bit counter API constant time */ + long count; /* doesn't count the tail */ +} oggpack_buffer; + +typedef struct oggbyte_buffer { + ogg_reference *baseref; + + ogg_reference *ref; + unsigned char *ptr; + long pos; + long end; +} oggbyte_buffer; + +typedef struct ogg_sync_state { + /* decode memory management pool */ + ogg_buffer_state *bufferpool; + + /* stream buffers */ + ogg_reference *fifo_head; + ogg_reference *fifo_tail; + long fifo_fill; + + /* stream sync management */ + int unsynced; + int headerbytes; + int bodybytes; + +} ogg_sync_state; + +typedef struct ogg_stream_state { + ogg_reference *header_head; + ogg_reference *header_tail; + ogg_reference *body_head; + ogg_reference *body_tail; + + int e_o_s; /* set when we have buffered the last + packet in the logical bitstream */ + int b_o_s; /* set after we've written the initial page + of a logical bitstream */ + long serialno; + long pageno; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ + ogg_int64_t granulepos; + + int lacing_fill; + ogg_uint32_t body_fill; + + /* decode-side state data */ + int holeflag; + int spanflag; + int clearflag; + int laceptr; + ogg_uint32_t body_fill_next; + +} ogg_stream_state; + +typedef struct { + ogg_reference *packet; + long bytes; + long b_o_s; + long e_o_s; + ogg_int64_t granulepos; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ +} ogg_packet; + +typedef struct { + ogg_reference *header; + int header_len; + ogg_reference *body; + long body_len; +} ogg_page; + +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ + +extern void oggpack_readinit(oggpack_buffer *b,ogg_reference *r); +extern long oggpack_look(oggpack_buffer *b,int bits); +extern void oggpack_adv(oggpack_buffer *b,int bits); +extern long oggpack_read(oggpack_buffer *b,int bits); +extern long oggpack_bytes(oggpack_buffer *b); +extern long oggpack_bits(oggpack_buffer *b); +extern int oggpack_eop(oggpack_buffer *b); + +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ + +extern ogg_sync_state *ogg_sync_create(void); +extern int ogg_sync_destroy(ogg_sync_state *oy); +extern int ogg_sync_reset(ogg_sync_state *oy); + +extern unsigned char *ogg_sync_bufferin(ogg_sync_state *oy, long size); +extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); + +/* Ogg BITSTREAM PRIMITIVES: general ***************************/ + +extern ogg_stream_state *ogg_stream_create(int serialno); +extern int ogg_stream_destroy(ogg_stream_state *os); +extern int ogg_stream_reset(ogg_stream_state *os); +extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); +extern int ogg_stream_eos(ogg_stream_state *os); + +extern int ogg_page_checksum_set(ogg_page *og); + +extern int ogg_page_version(ogg_page *og); +extern int ogg_page_continued(ogg_page *og); +extern int ogg_page_bos(ogg_page *og); +extern int ogg_page_eos(ogg_page *og); +extern ogg_int64_t ogg_page_granulepos(ogg_page *og); +extern ogg_uint32_t ogg_page_serialno(ogg_page *og); +extern ogg_uint32_t ogg_page_pageno(ogg_page *og); +extern int ogg_page_packets(ogg_page *og); +extern int ogg_page_getbuffer(ogg_page *og, unsigned char **buffer); + +extern int ogg_packet_release(ogg_packet *op); +extern int ogg_page_release(ogg_page *og); + +extern void ogg_page_dup(ogg_page *d, ogg_page *s); + +/* Ogg BITSTREAM PRIMITIVES: return codes ***************************/ + +#define OGG_SUCCESS 0 + +#define OGG_HOLE -10 +#define OGG_SPAN -11 +#define OGG_EVERSION -12 +#define OGG_ESERIAL -13 +#define OGG_EINVAL -14 +#define OGG_EEOS -15 + + +#ifdef __cplusplus +} +#endif + +#endif /* _OGG_H */ diff --git a/genplus-gx/core/tremor/os.h b/genplus-gx/core/tremor/os.h new file mode 100644 index 0000000000..95e6e27d92 --- /dev/null +++ b/genplus-gx/core/tremor/os.h @@ -0,0 +1,64 @@ +#ifndef _OS_H +#define _OS_H +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + + ********************************************************************/ + +#include +#include "os_types.h" + +#ifndef _V_IFDEFJAIL_H_ +# define _V_IFDEFJAIL_H_ + +# ifdef __GNUC__ +# define STIN static __inline__ +# elif _WIN32 +# define STIN static __inline +# endif +#else +# define STIN static +#endif + +#ifndef M_PI +# define M_PI (3.1415926536f) +#endif + +#ifdef _WIN32 +# include +# define rint(x) (floor((x)+0.5f)) +# define NO_FLOAT_MATH_LIB +# define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b)) +# define LITTLE_ENDIAN 1 +# define BYTE_ORDER LITTLE_ENDIAN +#endif + +#ifdef HAVE_ALLOCA_H +# include +#endif + +#ifdef USE_MEMORY_H +# include +#endif + +#ifndef min +# define min(x,y) ((x)>(y)?(y):(x)) +#endif + +#ifndef max +# define max(x,y) ((x)<(y)?(y):(x)) +#endif + +#endif /* _OS_H */ diff --git a/genplus-gx/core/tremor/os_types.h b/genplus-gx/core/tremor/os_types.h new file mode 100644 index 0000000000..8af289316b --- /dev/null +++ b/genplus-gx/core/tremor/os_types.h @@ -0,0 +1,42 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + + ********************************************************************/ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +#ifdef _LOW_ACCURACY_ +# define X(n) (((((n)>>22)+1)>>1) - ((((n)>>22)+1)>>9)) +# define LOOKUP_T const unsigned char +#else +# define X(n) (n) +# define LOOKUP_T const ogg_int32_t +#endif + +/* make it easy on the folks that want to compile the libs with a + different malloc than stdlib */ +#define _ogg_malloc malloc +#define _ogg_calloc calloc +#define _ogg_realloc realloc +#define _ogg_free free + +#include + +typedef int64_t ogg_int64_t; +typedef int32_t ogg_int32_t; +typedef uint32_t ogg_uint32_t; +typedef int16_t ogg_int16_t; + +#endif /* _OS_TYPES_H */ diff --git a/genplus-gx/core/tremor/registry.c b/genplus-gx/core/tremor/registry.c new file mode 100644 index 0000000000..c0b5fec0cc --- /dev/null +++ b/genplus-gx/core/tremor/registry.c @@ -0,0 +1,50 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: registry for floor, res backends and channel mappings + + ********************************************************************/ + +#include "ivorbiscodec.h" +#include "codec_internal.h" +#include "registry.h" +#include "misc.h" + + +/* seems like major overkill now; the backend numbers will grow into + the infrastructure soon enough */ + +extern vorbis_func_floor floor0_exportbundle; +extern vorbis_func_floor floor1_exportbundle; +extern vorbis_func_residue residue0_exportbundle; +extern vorbis_func_residue residue1_exportbundle; +extern vorbis_func_residue residue2_exportbundle; +extern vorbis_func_mapping mapping0_exportbundle; + +vorbis_func_floor *_floor_P[]={ + &floor0_exportbundle, + &floor1_exportbundle, +}; + +vorbis_func_residue *_residue_P[]={ + &residue0_exportbundle, + &residue1_exportbundle, + &residue2_exportbundle, +}; + +vorbis_func_mapping *_mapping_P[]={ + &mapping0_exportbundle, +}; + + + diff --git a/genplus-gx/core/tremor/registry.h b/genplus-gx/core/tremor/registry.h new file mode 100644 index 0000000000..2bc8068f69 --- /dev/null +++ b/genplus-gx/core/tremor/registry.h @@ -0,0 +1,40 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: registry for time, floor, res backends and channel mappings + + ********************************************************************/ + +#ifndef _V_REG_H_ +#define _V_REG_H_ + +#define VI_TRANSFORMB 1 +#define VI_WINDOWB 1 +#define VI_TIMEB 1 +#define VI_FLOORB 2 +#define VI_RESB 3 +#define VI_MAPB 1 + +#include "backends.h" + +#if defined(_WIN32) && defined(VORBISDLL_IMPORT) +# define EXTERN __declspec(dllimport) extern +#else +# define EXTERN extern +#endif + +EXTERN vorbis_func_floor *_floor_P[]; +EXTERN vorbis_func_residue *_residue_P[]; +EXTERN vorbis_func_mapping *_mapping_P[]; + +#endif diff --git a/genplus-gx/core/tremor/res012.c b/genplus-gx/core/tremor/res012.c new file mode 100644 index 0000000000..224b54ee8a --- /dev/null +++ b/genplus-gx/core/tremor/res012.c @@ -0,0 +1,342 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: residue backend 0, 1 and 2 implementation + + ********************************************************************/ + +#include +#include +#include +#include "ogg.h" +#include "ivorbiscodec.h" +#include "codec_internal.h" +#include "registry.h" +#include "codebook.h" +#include "misc.h" +#include "os.h" +#include "block.h" + +typedef struct { + vorbis_info_residue0 *info; + int map; + + int parts; + int stages; + codebook *fullbooks; + codebook *phrasebook; + codebook ***partbooks; + + int partvals; + int **decodemap; + +} vorbis_look_residue0; + +void res0_free_info(vorbis_info_residue *i){ + vorbis_info_residue0 *info=(vorbis_info_residue0 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +void res0_free_look(vorbis_look_residue *i){ + int j; + if(i){ + + vorbis_look_residue0 *look=(vorbis_look_residue0 *)i; + + for(j=0;jparts;j++) + if(look->partbooks[j])_ogg_free(look->partbooks[j]); + _ogg_free(look->partbooks); + for(j=0;jpartvals;j++) + _ogg_free(look->decodemap[j]); + _ogg_free(look->decodemap); + + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +static int ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static int icount(unsigned int v){ + int ret=0; + while(v){ + ret+=v&1; + v>>=1; + } + return(ret); +} + +/* vorbis_info is for range checking */ +vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){ + int j,acc=0; + vorbis_info_residue0 *info=(vorbis_info_residue0 *)_ogg_calloc(1,sizeof(*info)); + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + + info->begin=oggpack_read(opb,24); + info->end=oggpack_read(opb,24); + info->grouping=oggpack_read(opb,24)+1; + info->partitions=oggpack_read(opb,6)+1; + info->groupbook=oggpack_read(opb,8); + + for(j=0;jpartitions;j++){ + int cascade=oggpack_read(opb,3); + if(oggpack_read(opb,1)) + cascade|=(oggpack_read(opb,5)<<3); + info->secondstages[j]=cascade; + + acc+=icount(cascade); + } + for(j=0;jbooklist[j]=oggpack_read(opb,8); + + if(info->groupbook>=ci->books)goto errout; + for(j=0;jbooklist[j]>=ci->books)goto errout; + + return(info); + errout: + res0_free_info(info); + return(NULL); +} + +vorbis_look_residue *res0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm, + vorbis_info_residue *vr){ + vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; + vorbis_look_residue0 *look=(vorbis_look_residue0 *)_ogg_calloc(1,sizeof(*look)); + codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; + + int j,k,acc=0; + int dim; + int maxstage=0; + look->info=info; + look->map=vm->mapping; + + look->parts=info->partitions; + look->fullbooks=ci->fullbooks; + look->phrasebook=ci->fullbooks+info->groupbook; + dim=look->phrasebook->dim; + + look->partbooks=(codebook ***)_ogg_calloc(look->parts,sizeof(*look->partbooks)); + + for(j=0;jparts;j++){ + int stages=ilog(info->secondstages[j]); + if(stages){ + if(stages>maxstage)maxstage=stages; + look->partbooks[j]=(codebook **)_ogg_calloc(stages,sizeof(*look->partbooks[j])); + for(k=0;ksecondstages[j]&(1<partbooks[j][k]=ci->fullbooks+info->booklist[acc++]; +#ifdef TRAIN_RES + look->training_data[k][j]=calloc(look->partbooks[j][k]->entries, + sizeof(***look->training_data)); +#endif + } + } + } + + look->partvals=look->parts; + for(j=1;jpartvals*=look->parts; + look->stages=maxstage; + look->decodemap=(int **)_ogg_malloc(look->partvals*sizeof(*look->decodemap)); + for(j=0;jpartvals;j++){ + long val=j; + long mult=look->partvals/look->parts; + look->decodemap[j]=(int *)_ogg_malloc(dim*sizeof(*look->decodemap[j])); + for(k=0;kparts; + look->decodemap[j][k]=deco; + } + } + + return(look); +} + + +/* a truncated packet here just means 'stop working'; it's not an error */ +static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl, + ogg_int32_t **in,int ch, + long (*decodepart)(codebook *, ogg_int32_t *, + oggpack_buffer *,int,int)){ + + long i,j,k,l,s; + vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; + vorbis_info_residue0 *info=look->info; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int partitions_per_word=look->phrasebook->dim; + int max=vb->pcmend>>1; + int end=(info->endend:max); + int n=end-info->begin; + + if(n>0){ + int partvals=n/samples_per_partition; + int partwords=(partvals+partitions_per_word-1)/partitions_per_word; + int ***partword=(int ***)alloca(ch*sizeof(*partword)); + + for(j=0;jstages;s++){ + + /* each loop decodes on partition codeword containing + partitions_pre_word partitions */ + for(i=0,l=0;iphrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[j][l]=look->decodemap[temp]; + if(partword[j][l]==NULL)goto errout; + } + } + + /* now we decode residual values for the partitions */ + for(k=0;kbegin+i*samples_per_partition; + if(info->secondstages[partword[j][l][k]]&(1<partbooks[partword[j][l][k]][s]; + if(stagebook){ + if(decodepart(stagebook,in[j]+offset,&vb->opb, + samples_per_partition,-8)==-1)goto eopbreak; + } + } + } + } + } + } + errout: + eopbreak: + return(0); +} + +int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl, + ogg_int32_t **in,int *nonzero,int ch){ + int i,used=0; + for(i=0;iinfo; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int partitions_per_word=look->phrasebook->dim; + int max=(vb->pcmend*ch)>>1; + int end=(info->endend:max); + int n=end-info->begin; + + if(n>0){ + + int partvals=n/samples_per_partition; + int partwords=(partvals+partitions_per_word-1)/partitions_per_word; + int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword)); + int beginoff=info->begin/ch; + + for(i=0;istages;s++){ + for(i=0,l=0;iphrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[l]=look->decodemap[temp]; + if(partword[l]==NULL)goto errout; + } + + /* now we decode residual values for the partitions */ + for(k=0;ksecondstages[partword[l][k]]&(1<partbooks[partword[l][k]][s]; + + if(stagebook){ + if(vorbis_book_decodevv_add(stagebook,in, + i*samples_per_partition+beginoff,ch, + &vb->opb, + samples_per_partition,-8)==-1) + goto eopbreak; + } + } + } + } + } + errout: + eopbreak: + return(0); +} + + +vorbis_func_residue residue0_exportbundle={ + &res0_unpack, + &res0_look, + &res0_free_info, + &res0_free_look, + &res0_inverse +}; + +vorbis_func_residue residue1_exportbundle={ + &res0_unpack, + &res0_look, + &res0_free_info, + &res0_free_look, + &res1_inverse +}; + +vorbis_func_residue residue2_exportbundle={ + &res0_unpack, + &res0_look, + &res0_free_info, + &res0_free_look, + &res2_inverse +}; diff --git a/genplus-gx/core/tremor/sharedbook.c b/genplus-gx/core/tremor/sharedbook.c new file mode 100644 index 0000000000..8e074925d0 --- /dev/null +++ b/genplus-gx/core/tremor/sharedbook.c @@ -0,0 +1,439 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: basic shared codebook operations + + ********************************************************************/ + +#include +#include +#include +#include "ogg.h" +#include "misc.h" +#include "ivorbiscodec.h" +#include "codebook.h" + +/**** pack/unpack helpers ******************************************/ +int _ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +/* 32 bit float (not IEEE; nonnormalized mantissa + + biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm + Why not IEEE? It's just not that important here. */ + +#define VQ_FEXP 10 +#define VQ_FMAN 21 +#define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */ + +static ogg_int32_t _float32_unpack(long val,int *point){ + long mant=val&0x1fffff; + int sign=val&0x80000000; + long exp =(val&0x7fe00000L)>>VQ_FMAN; + + exp-=(VQ_FMAN-1)+VQ_FEXP_BIAS; + + if(mant){ + while(!(mant&0x40000000)){ + mant<<=1; + exp-=1; + } + + if(sign)mant= -mant; + }else{ + sign=0; + exp=-9999; + } + + *point=exp; + return mant; +} + +/* given a list of word lengths, generate a list of codewords. Works + for length ordered or unordered, always assigns the lowest valued + codewords first. Extended to handle unused entries (length 0) */ +ogg_uint32_t *_make_words(long *l,long n,long sparsecount){ + long i,j,count=0; + ogg_uint32_t marker[33]; + ogg_uint32_t *r=(ogg_uint32_t *)_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r)); + memset(marker,0,sizeof(marker)); + + for(i=0;i0){ + ogg_uint32_t entry=marker[length]; + + /* when we claim a node for an entry, we also claim the nodes + below it (pruning off the imagined tree that may have dangled + from it) as well as blocking the use of any nodes directly + above for leaves */ + + /* update ourself */ + if(length<32 && (entry>>length)){ + /* error condition; the lengths must specify an overpopulated tree */ + _ogg_free(r); + return(NULL); + } + r[count++]=entry; + + /* Look to see if the next shorter marker points to the node + above. if so, update it and repeat. */ + { + for(j=length;j>0;j--){ + + if(marker[j]&1){ + /* have to jump branches */ + if(j==1) + marker[1]++; + else + marker[j]=marker[j-1]<<1; + break; /* invariant says next upper marker would already + have been moved if it was on the same path */ + } + marker[j]++; + } + } + + /* prune the tree; the implicit invariant says all the longer + markers were dangling from our just-taken node. Dangle them + from our *new* node. */ + for(j=length+1;j<33;j++) + if((marker[j]>>1) == entry){ + entry=marker[j]; + marker[j]=marker[j-1]<<1; + }else + break; + }else + if(sparsecount==0)count++; + } + + /* bitreverse the words because our bitwise packer/unpacker is LSb + endian */ + for(i=0,count=0;i>j)&1; + } + + if(sparsecount){ + if(l[i]) + r[count++]=temp; + }else + r[count++]=temp; + } + + return(r); +} + +/* there might be a straightforward one-line way to do the below + that's portable and totally safe against roundoff, but I haven't + thought of it. Therefore, we opt on the side of caution */ +long _book_maptype1_quantvals(const static_codebook *b){ + /* get us a starting hint, we'll polish it below */ + int bits=_ilog(b->entries); + int vals=b->entries>>((bits-1)*(b->dim-1)/b->dim); + + while(1){ + long acc=1; + long acc1=1; + int i; + for(i=0;idim;i++){ + acc*=vals; + acc1*=vals+1; + } + if(acc<=b->entries && acc1>b->entries){ + return(vals); + }else{ + if(acc>b->entries){ + vals--; + }else{ + vals++; + } + } + } +} + +/* different than what _book_unquantize does for mainline: + we repack the book in a fixed point format that shares the same + binary point. Upon first use, we can shift point if needed */ + +/* we need to deal with two map types: in map type 1, the values are + generated algorithmically (each column of the vector counts through + the values in the quant vector). in map type 2, all the values came + in in an explicit list. Both value lists must be unpacked */ + +ogg_int32_t *_book_unquantize(const static_codebook *b,int n,int *sparsemap, + int *maxpoint){ + long j,k,count=0; + if(b->maptype==1 || b->maptype==2){ + int quantvals; + int minpoint,delpoint; + ogg_int32_t mindel=_float32_unpack(b->q_min,&minpoint); + ogg_int32_t delta=_float32_unpack(b->q_delta,&delpoint); + ogg_int32_t *r=(ogg_int32_t *)_ogg_calloc(n*b->dim,sizeof(*r)); + int *rp=(int *)_ogg_calloc(n*b->dim,sizeof(*rp)); + + *maxpoint=minpoint; + + /* maptype 1 and 2 both use a quantized value vector, but + different sizes */ + switch(b->maptype){ + case 1: + /* most of the time, entries%dimensions == 0, but we need to be + well defined. We define that the possible vales at each + scalar is values == entries/dim. If entries%dim != 0, we'll + have 'too few' values (values*dimentries;j++){ + if((sparsemap && b->lengthlist[j]) || !sparsemap){ + ogg_int32_t last=0; + int lastpoint=0; + int indexdiv=1; + for(k=0;kdim;k++){ + int index= (j/indexdiv)%quantvals; + int point=0; + int val=VFLOAT_MULTI(delta,delpoint, + abs(b->quantlist[index]),&point); + + val=VFLOAT_ADD(mindel,minpoint,val,point,&point); + val=VFLOAT_ADD(last,lastpoint,val,point,&point); + + if(b->q_sequencep){ + last=val; + lastpoint=point; + } + + if(sparsemap){ + r[sparsemap[count]*b->dim+k]=val; + rp[sparsemap[count]*b->dim+k]=point; + }else{ + r[count*b->dim+k]=val; + rp[count*b->dim+k]=point; + } + if(*maxpointentries;j++){ + if((sparsemap && b->lengthlist[j]) || !sparsemap){ + ogg_int32_t last=0; + int lastpoint=0; + + for(k=0;kdim;k++){ + int point=0; + int val=VFLOAT_MULTI(delta,delpoint, + abs(b->quantlist[j*b->dim+k]),&point); + + val=VFLOAT_ADD(mindel,minpoint,val,point,&point); + val=VFLOAT_ADD(last,lastpoint,val,point,&point); + + if(b->q_sequencep){ + last=val; + lastpoint=point; + } + + if(sparsemap){ + r[sparsemap[count]*b->dim+k]=val; + rp[sparsemap[count]*b->dim+k]=point; + }else{ + r[count*b->dim+k]=val; + rp[count*b->dim+k]=point; + } + if(*maxpointdim;j++) + if(rp[j]<*maxpoint) + r[j]>>=*maxpoint-rp[j]; + + _ogg_free(rp); + return(r); + } + return(NULL); +} + +void vorbis_staticbook_clear(static_codebook *b){ + if(b->quantlist)_ogg_free(b->quantlist); + if(b->lengthlist)_ogg_free(b->lengthlist); + memset(b,0,sizeof(*b)); + +} + +void vorbis_staticbook_destroy(static_codebook *b){ + vorbis_staticbook_clear(b); + _ogg_free(b); +} + +void vorbis_book_clear(codebook *b){ + /* static book is not cleared; we're likely called on the lookup and + the static codebook belongs to the info struct */ + if(b->valuelist)_ogg_free(b->valuelist); + if(b->codelist)_ogg_free(b->codelist); + + if(b->dec_index)_ogg_free(b->dec_index); + if(b->dec_codelengths)_ogg_free(b->dec_codelengths); + if(b->dec_firsttable)_ogg_free(b->dec_firsttable); + + memset(b,0,sizeof(*b)); +} + +static ogg_uint32_t bitreverse(ogg_uint32_t x){ + x= ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL); + x= ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL); + x= ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL); + x= ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL); + return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL); +} + +static int sort32a(const void *a,const void *b){ + return (**(ogg_uint32_t **)a>**(ogg_uint32_t **)b)- + (**(ogg_uint32_t **)a<**(ogg_uint32_t **)b); +} + +/* decode codebook arrangement is more heavily optimized than encode */ +int vorbis_book_init_decode(codebook *c,const static_codebook *s){ + int i,j,n=0,tabn; + int *sortindex; + memset(c,0,sizeof(*c)); + + /* count actually used entries */ + for(i=0;ientries;i++) + if(s->lengthlist[i]>0) + n++; + + c->entries=s->entries; + c->used_entries=n; + c->dim=s->dim; + + if(n>0){ + /* two different remappings go on here. + + First, we collapse the likely sparse codebook down only to + actually represented values/words. This collapsing needs to be + indexed as map-valueless books are used to encode original entry + positions as integers. + + Second, we reorder all vectors, including the entry index above, + by sorted bitreversed codeword to allow treeless decode. */ + + /* perform sort */ + ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); + ogg_uint32_t **codep=(ogg_uint32_t **)alloca(sizeof(*codep)*n); + + if(codes==NULL)goto err_out; + + for(i=0;icodelist=(ogg_uint32_t *)_ogg_malloc(n*sizeof(*c->codelist)); + /* the index is a reverse index */ + for(i=0;icodelist[sortindex[i]]=codes[i]; + _ogg_free(codes); + + + + c->valuelist=_book_unquantize(s,n,sortindex,&c->binarypoint); + c->dec_index=(int *)_ogg_malloc(n*sizeof(*c->dec_index)); + + for(n=0,i=0;ientries;i++) + if(s->lengthlist[i]>0) + c->dec_index[sortindex[n++]]=i; + + c->dec_codelengths=(char *)_ogg_malloc(n*sizeof(*c->dec_codelengths)); + for(n=0,i=0;ientries;i++) + if(s->lengthlist[i]>0) + c->dec_codelengths[sortindex[n++]]=s->lengthlist[i]; + + c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */ + if(c->dec_firsttablen<5)c->dec_firsttablen=5; + if(c->dec_firsttablen>8)c->dec_firsttablen=8; + + tabn=1<dec_firsttablen; + c->dec_firsttable=(ogg_uint32_t *)_ogg_calloc(tabn,sizeof(*c->dec_firsttable)); + c->dec_maxlength=0; + + for(i=0;idec_maxlengthdec_codelengths[i]) + c->dec_maxlength=c->dec_codelengths[i]; + if(c->dec_codelengths[i]<=c->dec_firsttablen){ + ogg_uint32_t orig=bitreverse(c->codelist[i]); + for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++) + c->dec_firsttable[orig|(j<dec_codelengths[i])]=i+1; + } + } + + /* now fill in 'unused' entries in the firsttable with hi/lo search + hints for the non-direct-hits */ + { + ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen); + long lo=0,hi=0; + + for(i=0;idec_firsttablen); + if(c->dec_firsttable[bitreverse(word)]==0){ + while((lo+1)codelist[lo+1]<=word)lo++; + while( hi=(c->codelist[hi]&mask))hi++; + + /* we only actually have 15 bits per hint to play with here. + In order to overflow gracefully (nothing breaks, efficiency + just drops), encode as the difference from the extremes. */ + { + unsigned long loval=lo; + unsigned long hival=n-hi; + + if(loval>0x7fff)loval=0x7fff; + if(hival>0x7fff)hival=0x7fff; + c->dec_firsttable[bitreverse(word)]= + 0x80000000UL | (loval<<15) | hival; + } + } + } + } + } + + return(0); + err_out: + vorbis_book_clear(c); + return(-1); +} + diff --git a/genplus-gx/core/tremor/synthesis.c b/genplus-gx/core/tremor/synthesis.c new file mode 100644 index 0000000000..962c7309ef --- /dev/null +++ b/genplus-gx/core/tremor/synthesis.c @@ -0,0 +1,113 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: single-block PCM synthesis + last mod: $Id: synthesis.c,v 1.4 2003/03/29 03:07:21 xiphmont Exp $ + + ********************************************************************/ + +#include +#include "ogg.h" +#include "ivorbiscodec.h" +#include "codec_internal.h" +#include "registry.h" +#include "misc.h" +#include "block.h" + +int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep){ + vorbis_dsp_state *vd=vb->vd; + private_state *b=(private_state *)vd->backend_state; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + oggpack_buffer *opb=&vb->opb; + int type,mode,i; + + /* first things first. Make sure decode is ready */ + _vorbis_block_ripcord(vb); + oggpack_readinit(opb,op->packet); + + /* Check the packet type */ + if(oggpack_read(opb,1)!=0){ + /* Oops. This is not an audio data packet */ + return(OV_ENOTAUDIO); + } + + /* read our mode and pre/post windowsize */ + mode=oggpack_read(opb,b->modebits); + if(mode==-1)return(OV_EBADPACKET); + + vb->mode=mode; + vb->W=ci->mode_param[mode]->blockflag; + if(vb->W){ + vb->lW=oggpack_read(opb,1); + vb->nW=oggpack_read(opb,1); + if(vb->nW==-1) return(OV_EBADPACKET); + }else{ + vb->lW=0; + vb->nW=0; + } + + /* more setup */ + vb->granulepos=op->granulepos; + vb->sequence=op->packetno-3; /* first block is third packet */ + vb->eofflag=op->e_o_s; + + if(decodep){ + /* alloc pcm passback storage */ + vb->pcmend=ci->blocksizes[vb->W]; + vb->pcm=(ogg_int32_t **)_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); + for(i=0;ichannels;i++) + vb->pcm[i]=(ogg_int32_t *)_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); + + /* unpack_header enforces range checking */ + type=ci->map_type[ci->mode_param[mode]->mapping]; + + return(_mapping_P[type]->inverse(vb,b->mode[mode])); + }else{ + /* no pcm */ + vb->pcmend=0; + vb->pcm=NULL; + + return(0); + } +} + +long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ + codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + oggpack_buffer opb; + int mode; + + oggpack_readinit(&opb,op->packet); + + /* Check the packet type */ + if(oggpack_read(&opb,1)!=0){ + /* Oops. This is not an audio data packet */ + return(OV_ENOTAUDIO); + } + + { + int modebits=0; + int v=ci->modes; + while(v>1){ + modebits++; + v>>=1; + } + + /* read our mode and pre/post windowsize */ + mode=oggpack_read(&opb,modebits); + } + if(mode==-1)return(OV_EBADPACKET); + return(ci->blocksizes[ci->mode_param[mode]->blockflag]); +} + + diff --git a/genplus-gx/core/tremor/vorbisfile.c b/genplus-gx/core/tremor/vorbisfile.c new file mode 100644 index 0000000000..0230c93e03 --- /dev/null +++ b/genplus-gx/core/tremor/vorbisfile.c @@ -0,0 +1,1597 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id: vorbisfile.c,v 1.6 2003/03/30 23:40:56 xiphmont Exp $ + + ********************************************************************/ + +#include +#include +#include +#include +#include + +#include "ivorbiscodec.h" +#include "ivorbisfile.h" + +#include "misc.h" + +/* A 'chained bitstream' is a Vorbis bitstream that contains more than + one logical bitstream arranged end to end (the only form of Ogg + multiplexing allowed in a Vorbis bitstream; grouping [parallel + multiplexing] is not allowed in Vorbis) */ + +/* A Vorbis file can be played beginning to end (streamed) without + worrying ahead of time about chaining (see decoder_example.c). If + we have the whole file, however, and want random access + (seeking/scrubbing) or desire to know the total length/time of a + file, we need to account for the possibility of chaining. */ + +/* We can handle things a number of ways; we can determine the entire + bitstream structure right off the bat, or find pieces on demand. + This example determines and caches structure for the entire + bitstream, but builds a virtual decoder on the fly when moving + between links in the chain. */ + +/* There are also different ways to implement seeking. Enough + information exists in an Ogg bitstream to seek to + sample-granularity positions in the output. Or, one can seek by + picking some portion of the stream roughly in the desired area if + we only want coarse navigation through the stream. */ + +/************************************************************************* + * Many, many internal helpers. The intention is not to be confusing; + * rampant duplication and monolithic function implementation would be + * harder to understand anyway. The high level functions are last. Begin + * grokking near the end of the file */ + + +/* read a little more data from the file/pipe into the ogg_sync framer */ +static long _get_data(OggVorbis_File *vf){ + errno=0; + if(vf->datasource){ + unsigned char *buffer=ogg_sync_bufferin(vf->oy,CHUNKSIZE); + long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource); + if(bytes>0)ogg_sync_wrote(vf->oy,bytes); + +#ifndef GEKKO + else if(bytes==0 && errno ) +#else + // Not sure what is up with this... appears that EOVERFLOW is set whenever + // we read to the end of the file... + // original patch by raz0red for Mednafen-Wii + else if(bytes==0 && errno && errno != EOVERFLOW ) +#endif + { + return(-1); + } + return(bytes); + }else + return(0); +} + +/* save a tiny smidge of verbosity to make the code more readable */ +static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){ + if(vf->datasource){ + (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET); + vf->offset=offset; + ogg_sync_reset(vf->oy); + }else{ + /* shouldn't happen unless someone writes a broken callback */ + return; + } +} + +/* The read/seek functions track absolute position within the stream */ + +/* from the head of the stream, get the next page. boundary specifies + if the function is allowed to fetch more data from the stream (and + how much) or only use internally buffered data. + + boundary: -1) unbounded search + 0) read no additional data; use cached only + n) search for a new page beginning for n bytes + + return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD) + n) found a page at absolute offset n + + produces a refcounted page */ + +static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og, + ogg_int64_t boundary){ + if(boundary>0)boundary+=vf->offset; + while(1){ + long more; + + if(boundary>0 && vf->offset>=boundary)return(OV_FALSE); + more=ogg_sync_pageseek(vf->oy,og); + + if(more<0){ + /* skipped n bytes */ + vf->offset-=more; + }else{ + if(more==0){ + /* send more paramedics */ + if(!boundary)return(OV_FALSE); + { + long ret=_get_data(vf); + if(ret==0)return(OV_EOF); + if(ret<0)return(OV_EREAD); + } + }else{ + /* got a page. Return the offset at the page beginning, + advance the internal offset past the page end */ + ogg_int64_t ret=vf->offset; + vf->offset+=more; + return(ret); + + } + } + } +} + +/* find the latest page beginning before the current stream cursor + position. Much dirtier than the above as Ogg doesn't have any + backward search linkage. no 'readp' as it will certainly have to + read. */ +/* returns offset or OV_EREAD, OV_FAULT and produces a refcounted page */ + +static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){ + ogg_int64_t begin=vf->offset; + ogg_int64_t end=begin; + ogg_int64_t ret; + ogg_int64_t offset=-1; + + while(offset==-1){ + begin-=CHUNKSIZE; + if(begin<0) + begin=0; + _seek_helper(vf,begin); + while(vf->offsetoffset); + if(ret==OV_EREAD)return(OV_EREAD); + if(ret<0){ + break; + }else{ + offset=ret; + } + } + } + + /* we have the offset. Actually snork and hold the page now */ + _seek_helper(vf,offset); + ret=_get_next_page(vf,og,CHUNKSIZE); + if(ret<0) + /* this shouldn't be possible */ + return(OV_EFAULT); + + return(offset); +} + +/* finds each bitstream link one at a time using a bisection search + (has to begin by knowing the offset of the lb's initial page). + Recurses for each link so it can alloc the link storage after + finding them all, then unroll and fill the cache at the same time */ +static int _bisect_forward_serialno(OggVorbis_File *vf, + ogg_int64_t begin, + ogg_int64_t searched, + ogg_int64_t end, + ogg_uint32_t currentno, + long m){ + ogg_int64_t endsearched=end; + ogg_int64_t next=end; + ogg_page og={0,0,0,0}; + ogg_int64_t ret; + + /* the below guards against garbage seperating the last and + first pages of two links. */ + while(searched=0)next=ret; + }else{ + searched=ret+og.header_len+og.body_len; + } + ogg_page_release(&og); + } + + _seek_helper(vf,next); + ret=_get_next_page(vf,&og,-1); + if(ret==OV_EREAD)return(OV_EREAD); + + if(searched>=end || ret<0){ + ogg_page_release(&og); + vf->links=m+1; + vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets)); + vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos)); + vf->offsets[m+1]=searched; + }else{ + ret=_bisect_forward_serialno(vf,next,vf->offset, + end,ogg_page_serialno(&og),m+1); + ogg_page_release(&og); + if(ret==OV_EREAD)return(OV_EREAD); + } + + vf->offsets[m]=begin; + vf->serialnos[m]=currentno; + return(0); +} + +/* uses the local ogg_stream storage in vf; this is important for + non-streaming input sources */ +/* consumes the page that's passed in (if any) */ + +static int _fetch_headers(OggVorbis_File *vf, + vorbis_info *vi, + vorbis_comment *vc, + ogg_uint32_t *serialno, + ogg_page *og_ptr){ + ogg_page og={0,0,0,0}; + ogg_packet op={0,0,0,0,0,0}; + int i,ret; + + if(!og_ptr){ + ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE); + if(llret==OV_EREAD)return(OV_EREAD); + if(llret<0)return OV_ENOTVORBIS; + og_ptr=&og; + } + + ogg_stream_reset_serialno(vf->os,ogg_page_serialno(og_ptr)); + if(serialno)*serialno=vf->os->serialno; + vf->ready_state=STREAMSET; + + /* extract the initial header from the first page and verify that the + Ogg bitstream is in fact Vorbis data */ + + vorbis_info_init(vi); + vorbis_comment_init(vc); + + i=0; + while(i<3){ + ogg_stream_pagein(vf->os,og_ptr); + while(i<3){ + int result=ogg_stream_packetout(vf->os,&op); + if(result==0)break; + if(result==-1){ + ret=OV_EBADHEADER; + goto bail_header; + } + if((ret=vorbis_synthesis_headerin(vi,vc,&op))){ + goto bail_header; + } + i++; + } + if(i<3) + if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){ + ret=OV_EBADHEADER; + goto bail_header; + } + } + + ogg_packet_release(&op); + ogg_page_release(&og); + return 0; + + bail_header: + ogg_packet_release(&op); + ogg_page_release(&og); + vorbis_info_clear(vi); + vorbis_comment_clear(vc); + vf->ready_state=OPENED; + + return ret; +} + +/* last step of the OggVorbis_File initialization; get all the + vorbis_info structs and PCM positions. Only called by the seekable + initialization (local stream storage is hacked slightly; pay + attention to how that's done) */ + +/* this is void and does not propogate errors up because we want to be + able to open and use damaged bitstreams as well as we can. Just + watch out for missing information for links in the OggVorbis_File + struct */ +static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){ + ogg_page og={0,0,0,0}; + int i; + ogg_int64_t ret; + + vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi)); + vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc)); + vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets)); + vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths)); + + for(i=0;ilinks;i++){ + if(i==0){ + /* we already grabbed the initial header earlier. Just set the offset */ + vf->dataoffsets[i]=dataoffset; + _seek_helper(vf,dataoffset); + + }else{ + + /* seek to the location of the initial header */ + + _seek_helper(vf,vf->offsets[i]); + if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){ + vf->dataoffsets[i]=-1; + }else{ + vf->dataoffsets[i]=vf->offset; + } + } + + /* fetch beginning PCM offset */ + + if(vf->dataoffsets[i]!=-1){ + ogg_int64_t accumulated=0,pos; + long lastblock=-1; + int result; + + ogg_stream_reset_serialno(vf->os,vf->serialnos[i]); + + while(1){ + ogg_packet op={0,0,0,0,0,0}; + + ret=_get_next_page(vf,&og,-1); + if(ret<0) + /* this should not be possible unless the file is + truncated/mangled */ + break; + + if(ogg_page_serialno(&og)!=vf->serialnos[i]) + break; + + pos=ogg_page_granulepos(&og); + + /* count blocksizes of all frames in the page */ + ogg_stream_pagein(vf->os,&og); + while((result=ogg_stream_packetout(vf->os,&op))){ + if(result>0){ /* ignore holes */ + long thisblock=vorbis_packet_blocksize(vf->vi+i,&op); + if(lastblock!=-1) + accumulated+=(lastblock+thisblock)>>2; + lastblock=thisblock; + } + } + ogg_packet_release(&op); + + if(pos!=-1){ + /* pcm offset of last packet on the first audio page */ + accumulated= pos-accumulated; + break; + } + } + + /* less than zero? This is a stream with samples trimmed off + the beginning, a normal occurrence; set the offset to zero */ + if(accumulated<0)accumulated=0; + + vf->pcmlengths[i*2]=accumulated; + } + + /* get the PCM length of this link. To do this, + get the last page of the stream */ + { + ogg_int64_t end=vf->offsets[i+1]; + _seek_helper(vf,end); + + while(1){ + ret=_get_prev_page(vf,&og); + if(ret<0){ + /* this should not be possible */ + vorbis_info_clear(vf->vi+i); + vorbis_comment_clear(vf->vc+i); + break; + } + if(ogg_page_granulepos(&og)!=-1){ + vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2]; + break; + } + vf->offset=ret; + } + } + } + ogg_page_release(&og); +} + +static void _make_decode_ready(OggVorbis_File *vf){ + if(vf->ready_state!=STREAMSET)return; + if(vf->seekable){ + vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link); + }else{ + vorbis_synthesis_init(&vf->vd,vf->vi); + } + vorbis_block_init(&vf->vd,&vf->vb); + vf->ready_state=INITSET; + vf->bittrack=0; + vf->samptrack=0; + return; +} + +static int _open_seekable2(OggVorbis_File *vf){ + ogg_uint32_t serialno=vf->current_serialno; + ogg_uint32_t tempserialno; + ogg_int64_t dataoffset=vf->offset, end; + ogg_page og={0,0,0,0}; + + /* we're partially open and have a first link header state in + storage in vf */ + /* we can seek, so set out learning all about this file */ + (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END); + vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource); + + /* We get the offset for the last page of the physical bitstream. + Most OggVorbis files will contain a single logical bitstream */ + end=_get_prev_page(vf,&og); + if(end<0)return(end); + + /* more than one logical bitstream? */ + tempserialno=ogg_page_serialno(&og); + ogg_page_release(&og); + + if(tempserialno!=serialno){ + + /* Chained bitstream. Bisect-search each logical bitstream + section. Do so based on serial number only */ + if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD); + + }else{ + + /* Only one logical bitstream */ + if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD); + + } + + /* the initial header memory is referenced by vf after; don't free it */ + _prefetch_all_headers(vf,dataoffset); + return(ov_raw_seek(vf,0)); +} + +/* clear out the current logical bitstream decoder */ +static void _decode_clear(OggVorbis_File *vf){ + vorbis_dsp_clear(&vf->vd); + vorbis_block_clear(&vf->vb); + vf->ready_state=OPENED; +} + +/* fetch and process a packet. Handles the case where we're at a + bitstream boundary and dumps the decoding machine. If the decoding + machine is unloaded, it loads it. It also keeps pcm_offset up to + date (seek and read both use this. seek uses a special hack with + readp). + + return: <0) error, OV_HOLE (lost packet) or OV_EOF + 0) need more data (only if readp==0) + 1) got a packet +*/ + +static int _fetch_and_process_packet(OggVorbis_File *vf, + int readp, + int spanp){ + ogg_page og={0,0,0,0}; + ogg_packet op={0,0,0,0,0,0}; + int ret=0; + + /* handle one packet. Try to fetch it from current stream state */ + /* extract packets from page */ + while(1){ + + /* process a packet if we can. If the machine isn't loaded, + neither is a page */ + if(vf->ready_state==INITSET){ + while(1) { + int result=ogg_stream_packetout(vf->os,&op); + ogg_int64_t granulepos; + + if(result<0){ + ret=OV_HOLE; /* hole in the data. */ + goto cleanup; + } + if(result>0){ + /* got a packet. process it */ + granulepos=op.granulepos; + if(!vorbis_synthesis(&vf->vb,&op,1)){ /* lazy check for lazy + header handling. The + header packets aren't + audio, so if/when we + submit them, + vorbis_synthesis will + reject them */ + + /* suck in the synthesis data and track bitrate */ + { + int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL); + /* for proper use of libvorbis within libvorbisfile, + oldsamples will always be zero. */ + if(oldsamples){ + ret=OV_EFAULT; + goto cleanup; + } + + vorbis_synthesis_blockin(&vf->vd,&vf->vb); + vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples; + vf->bittrack+=op.bytes*8; + } + + /* update the pcm offset. */ + if(granulepos!=-1 && !op.e_o_s){ + int link=(vf->seekable?vf->current_link:0); + int i,samples; + + /* this packet has a pcm_offset on it (the last packet + completed on a page carries the offset) After processing + (above), we know the pcm position of the *last* sample + ready to be returned. Find the offset of the *first* + + As an aside, this trick is inaccurate if we begin + reading anew right at the last page; the end-of-stream + granulepos declares the last frame in the stream, and the + last packet of the last page may be a partial frame. + So, we need a previous granulepos from an in-sequence page + to have a reference point. Thus the !op.e_o_s clause + above */ + + if(vf->seekable && link>0) + granulepos-=vf->pcmlengths[link*2]; + if(granulepos<0)granulepos=0; /* actually, this + shouldn't be possible + here unless the stream + is very broken */ + + samples=vorbis_synthesis_pcmout(&vf->vd,NULL); + + granulepos-=samples; + for(i=0;ipcmlengths[i*2+1]; + vf->pcm_offset=granulepos; + } + ret=1; + goto cleanup; + } + } + else + break; + } + } + + if(vf->ready_state>=OPENED){ + int ret; + if(!readp){ + ret=0; + goto cleanup; + } + if((ret=_get_next_page(vf,&og,-1))<0){ + ret=OV_EOF; /* eof. leave unitialized */ + goto cleanup; + } + + /* bitrate tracking; add the header's bytes here, the body bytes + are done by packet above */ + vf->bittrack+=og.header_len*8; + + /* has our decoding just traversed a bitstream boundary? */ + if(vf->ready_state==INITSET){ + if(vf->current_serialno!=ogg_page_serialno(&og)){ + if(!spanp){ + ret=OV_EOF; + goto cleanup; + } + + _decode_clear(vf); + + if(!vf->seekable){ + vorbis_info_clear(vf->vi); + vorbis_comment_clear(vf->vc); + } + } + } + } + + /* Do we need to load a new machine before submitting the page? */ + /* This is different in the seekable and non-seekable cases. + + In the seekable case, we already have all the header + information loaded and cached; we just initialize the machine + with it and continue on our merry way. + + In the non-seekable (streaming) case, we'll only be at a + boundary if we just left the previous logical bitstream and + we're now nominally at the header of the next bitstream + */ + + if(vf->ready_state!=INITSET){ + int link; + + if(vf->ready_stateseekable){ + vf->current_serialno=ogg_page_serialno(&og); + + /* match the serialno to bitstream section. We use this rather than + offset positions to avoid problems near logical bitstream + boundaries */ + for(link=0;linklinks;link++) + if(vf->serialnos[link]==vf->current_serialno)break; + if(link==vf->links){ + ret=OV_EBADLINK; /* sign of a bogus stream. error out, + leave machine uninitialized */ + goto cleanup; + } + + vf->current_link=link; + + ogg_stream_reset_serialno(vf->os,vf->current_serialno); + vf->ready_state=STREAMSET; + + }else{ + /* we're streaming */ + /* fetch the three header packets, build the info struct */ + + int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og); + if(ret) goto cleanup; + vf->current_link++; + link=0; + } + } + + _make_decode_ready(vf); + } + ogg_stream_pagein(vf->os,&og); + } + cleanup: + ogg_packet_release(&op); + ogg_page_release(&og); + return ret; +} + +/* if, eg, 64 bit stdio is configured by default, this will build with + fseek64 */ +static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){ + if(f==NULL)return(-1); + return fseek(f,off,whence); +} + +static int _ov_open1(void *f,OggVorbis_File *vf,char *initial, + long ibytes, ov_callbacks callbacks){ + int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1); + int ret; + + memset(vf,0,sizeof(*vf)); + vf->datasource=f; + vf->callbacks = callbacks; + + /* init the framing state */ + vf->oy=ogg_sync_create(); + + /* perhaps some data was previously read into a buffer for testing + against other stream types. Allow initialization from this + previously read data (as we may be reading from a non-seekable + stream) */ + if(initial){ + unsigned char *buffer=ogg_sync_bufferin(vf->oy,ibytes); + memcpy(buffer,initial,ibytes); + ogg_sync_wrote(vf->oy,ibytes); + } + + /* can we seek? Stevens suggests the seek test was portable */ + if(offsettest!=-1)vf->seekable=1; + + /* No seeking yet; Set up a 'single' (current) logical bitstream + entry for partial open */ + vf->links=1; + vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi)); + vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc)); + vf->os=ogg_stream_create(-1); /* fill in the serialno later */ + + /* Try to fetch the headers, maintaining all the storage */ + if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){ + vf->datasource=NULL; + ov_clear(vf); + }else if(vf->ready_state < PARTOPEN) + vf->ready_state=PARTOPEN; + return(ret); +} + +static int _ov_open2(OggVorbis_File *vf){ + if(vf->ready_state < OPENED) + vf->ready_state=OPENED; + if(vf->seekable){ + int ret=_open_seekable2(vf); + if(ret){ + vf->datasource=NULL; + ov_clear(vf); + } + return(ret); + } + return 0; +} + + +/* clear out the OggVorbis_File struct */ +int ov_clear(OggVorbis_File *vf){ + if(vf){ + vorbis_block_clear(&vf->vb); + vorbis_dsp_clear(&vf->vd); + ogg_stream_destroy(vf->os); + + if(vf->vi && vf->links){ + int i; + for(i=0;ilinks;i++){ + vorbis_info_clear(vf->vi+i); + vorbis_comment_clear(vf->vc+i); + } + _ogg_free(vf->vi); + _ogg_free(vf->vc); + } + if(vf->dataoffsets)_ogg_free(vf->dataoffsets); + if(vf->pcmlengths)_ogg_free(vf->pcmlengths); + if(vf->serialnos)_ogg_free(vf->serialnos); + if(vf->offsets)_ogg_free(vf->offsets); + ogg_sync_destroy(vf->oy); + + if(vf->datasource)(vf->callbacks.close_func)(vf->datasource); + memset(vf,0,sizeof(*vf)); + } +#ifdef DEBUG_LEAKS + _VDBG_dump(); +#endif + return(0); +} + +/* inspects the OggVorbis file and finds/documents all the logical + bitstreams contained in it. Tries to be tolerant of logical + bitstream sections that are truncated/woogie. + + return: -1) error + 0) OK +*/ + +int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes, + ov_callbacks callbacks){ + int ret=_ov_open1(f,vf,initial,ibytes,callbacks); + if(ret)return ret; + return _ov_open2(vf); +} + +int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){ + ov_callbacks callbacks = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell + }; + + return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks); +} + +/* Only partially open the vorbis file; test for Vorbisness, and load + the headers for the first chain. Do not seek (although test for + seekability). Use ov_test_open to finish opening the file, else + ov_clear to close/free it. Same return codes as open. */ + +int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes, + ov_callbacks callbacks) +{ + return _ov_open1(f,vf,initial,ibytes,callbacks); +} + +int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){ + ov_callbacks callbacks = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell + }; + + return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks); +} + +int ov_test_open(OggVorbis_File *vf){ + if(vf->ready_state!=PARTOPEN)return(OV_EINVAL); + return _ov_open2(vf); +} + +/* How many logical bitstreams in this physical bitstream? */ +long ov_streams(OggVorbis_File *vf){ + return vf->links; +} + +/* Is the FILE * associated with vf seekable? */ +long ov_seekable(OggVorbis_File *vf){ + return vf->seekable; +} + +/* returns the bitrate for a given logical bitstream or the entire + physical bitstream. If the file is open for random access, it will + find the *actual* average bitrate. If the file is streaming, it + returns the nominal bitrate (if set) else the average of the + upper/lower bounds (if set) else -1 (unset). + + If you want the actual bitrate field settings, get them from the + vorbis_info structs */ + +long ov_bitrate(OggVorbis_File *vf,int i){ + if(vf->ready_state=vf->links)return(OV_EINVAL); + if(!vf->seekable && i!=0)return(ov_bitrate(vf,0)); + if(i<0){ + ogg_int64_t bits=0; + int i; + for(i=0;ilinks;i++) + bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8; + /* This once read: return(rint(bits/ov_time_total(vf,-1))); + * gcc 3.x on x86 miscompiled this at optimisation level 2 and above, + * so this is slightly transformed to make it work. + */ + return(bits*1000/ov_time_total(vf,-1)); + }else{ + if(vf->seekable){ + /* return the actual bitrate */ + return((vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i)); + }else{ + /* return nominal if set */ + if(vf->vi[i].bitrate_nominal>0){ + return vf->vi[i].bitrate_nominal; + }else{ + if(vf->vi[i].bitrate_upper>0){ + if(vf->vi[i].bitrate_lower>0){ + return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2; + }else{ + return vf->vi[i].bitrate_upper; + } + } + return(OV_FALSE); + } + } + } +} + +/* returns the actual bitrate since last call. returns -1 if no + additional data to offer since last call (or at beginning of stream), + EINVAL if stream is only partially open +*/ +long ov_bitrate_instant(OggVorbis_File *vf){ + int link=(vf->seekable?vf->current_link:0); + long ret; + if(vf->ready_statesamptrack==0)return(OV_FALSE); + ret=vf->bittrack/vf->samptrack*vf->vi[link].rate; + vf->bittrack=0; + vf->samptrack=0; + return(ret); +} + +/* Guess */ +long ov_serialnumber(OggVorbis_File *vf,int i){ + if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1)); + if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1)); + if(i<0){ + return(vf->current_serialno); + }else{ + return(vf->serialnos[i]); + } +} + +/* returns: total raw (compressed) length of content if i==-1 + raw (compressed) length of that logical bitstream for i==0 to n + OV_EINVAL if the stream is not seekable (we can't know the length) + or if stream is only partially open +*/ +ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){ + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); + if(i<0){ + ogg_int64_t acc=0; + int i; + for(i=0;ilinks;i++) + acc+=ov_raw_total(vf,i); + return(acc); + }else{ + return(vf->offsets[i+1]-vf->offsets[i]); + } +} + +/* returns: total PCM length (samples) of content if i==-1 PCM length + (samples) of that logical bitstream for i==0 to n + OV_EINVAL if the stream is not seekable (we can't know the + length) or only partially open +*/ +ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){ + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); + if(i<0){ + ogg_int64_t acc=0; + int i; + for(i=0;ilinks;i++) + acc+=ov_pcm_total(vf,i); + return(acc); + }else{ + return(vf->pcmlengths[i*2+1]); + } +} + +/* returns: total milliseconds of content if i==-1 + milliseconds in that logical bitstream for i==0 to n + OV_EINVAL if the stream is not seekable (we can't know the + length) or only partially open +*/ +ogg_int64_t ov_time_total(OggVorbis_File *vf,int i){ + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); + if(i<0){ + ogg_int64_t acc=0; + int i; + for(i=0;ilinks;i++) + acc+=ov_time_total(vf,i); + return(acc); + }else{ + return(((ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi[i].rate); + } +} + +/* seek to an offset relative to the *compressed* data. This also + scans packets to update the PCM cursor. It will cross a logical + bitstream boundary, but only if it can't get any packets out of the + tail of the bitstream we seek to (so no surprises). + + returns zero on success, nonzero on failure */ + +int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){ + ogg_stream_state *work_os=NULL; + ogg_page og={0,0,0,0}; + ogg_packet op={0,0,0,0,0,0}; + + if(vf->ready_stateseekable) + return(OV_ENOSEEK); /* don't dump machine if we can't seek */ + + if(pos<0 || pos>vf->end)return(OV_EINVAL); + + /* don't yet clear out decoding machine (if it's initialized), in + the case we're in the same link. Restart the decode lapping, and + let _fetch_and_process_packet deal with a potential bitstream + boundary */ + vf->pcm_offset=-1; + ogg_stream_reset_serialno(vf->os, + vf->current_serialno); /* must set serialno */ + vorbis_synthesis_restart(&vf->vd); + + _seek_helper(vf,pos); + + /* we need to make sure the pcm_offset is set, but we don't want to + advance the raw cursor past good packets just to get to the first + with a granulepos. That's not equivalent behavior to beginning + decoding as immediately after the seek position as possible. + + So, a hack. We use two stream states; a local scratch state and + the shared vf->os stream state. We use the local state to + scan, and the shared state as a buffer for later decode. + + Unfortuantely, on the last page we still advance to last packet + because the granulepos on the last page is not necessarily on a + packet boundary, and we need to make sure the granpos is + correct. + */ + + { + int lastblock=0; + int accblock=0; + int thisblock; + int eosflag=0; + + work_os=ogg_stream_create(vf->current_serialno); /* get the memory ready */ + while(1){ + if(vf->ready_state>=STREAMSET){ + /* snarf/scan a packet if we can */ + int result=ogg_stream_packetout(work_os,&op); + + if(result>0){ + + if(vf->vi[vf->current_link].codec_setup){ + thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); + if(thisblock<0){ + ogg_stream_packetout(vf->os,NULL); + thisblock=0; + }else{ + + if(eosflag) + ogg_stream_packetout(vf->os,NULL); + else + if(lastblock)accblock+=(lastblock+thisblock)>>2; + } + + if(op.granulepos!=-1){ + int i,link=vf->current_link; + ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2]; + if(granulepos<0)granulepos=0; + + for(i=0;ipcmlengths[i*2+1]; + vf->pcm_offset=granulepos-accblock; + break; + } + lastblock=thisblock; + continue; + }else + ogg_stream_packetout(vf->os,NULL); + } + } + + if(!lastblock){ + if(_get_next_page(vf,&og,-1)<0){ + vf->pcm_offset=ov_pcm_total(vf,-1); + break; + } + }else{ + /* huh? Bogus stream with packets but no granulepos */ + vf->pcm_offset=-1; + break; + } + + /* has our decoding just traversed a bitstream boundary? */ + if(vf->ready_state>=STREAMSET) + if(vf->current_serialno!=ogg_page_serialno(&og)){ + _decode_clear(vf); /* clear out stream state */ + ogg_stream_destroy(work_os); + } + + if(vf->ready_statecurrent_serialno=ogg_page_serialno(&og); + for(link=0;linklinks;link++) + if(vf->serialnos[link]==vf->current_serialno)break; + if(link==vf->links) + goto seek_error; /* sign of a bogus stream. error out, + leave machine uninitialized */ + + vf->current_link=link; + + ogg_stream_reset_serialno(vf->os,vf->current_serialno); + ogg_stream_reset_serialno(work_os,vf->current_serialno); + vf->ready_state=STREAMSET; + + } + + { + ogg_page dup; + ogg_page_dup(&dup,&og); + eosflag=ogg_page_eos(&og); + ogg_stream_pagein(vf->os,&og); + ogg_stream_pagein(work_os,&dup); + } + } + } + + ogg_packet_release(&op); + ogg_page_release(&og); + ogg_stream_destroy(work_os); + vf->bittrack=0; + vf->samptrack=0; + return(0); + + seek_error: + ogg_packet_release(&op); + ogg_page_release(&og); + + /* dump the machine so we're in a known state */ + vf->pcm_offset=-1; + ogg_stream_destroy(work_os); + _decode_clear(vf); + return OV_EBADLINK; +} + +/* Page granularity seek (faster than sample granularity because we + don't do the last bit of decode to find a specific sample). + + Seek to the last [granule marked] page preceeding the specified pos + location, such that decoding past the returned point will quickly + arrive at the requested position. */ +int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){ + int link=-1; + ogg_int64_t result=0; + ogg_int64_t total=ov_pcm_total(vf,-1); + ogg_page og={0,0,0,0}; + ogg_packet op={0,0,0,0,0,0}; + + if(vf->ready_stateseekable)return(OV_ENOSEEK); + if(pos<0 || pos>total)return(OV_EINVAL); + + /* which bitstream section does this pcm offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + total-=vf->pcmlengths[link*2+1]; + if(pos>=total)break; + } + + /* search within the logical bitstream for the page with the highest + pcm_pos preceeding (or equal to) pos. There is a danger here; + missing pages or incorrect frame number information in the + bitstream could make our task impossible. Account for that (it + would be an error condition) */ + + /* new search algorithm by HB (Nicholas Vinen) */ + { + ogg_int64_t end=vf->offsets[link+1]; + ogg_int64_t begin=vf->offsets[link]; + ogg_int64_t begintime = vf->pcmlengths[link*2]; + ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime; + ogg_int64_t target=pos-total+begintime; + ogg_int64_t best=begin; + + while(beginoffset); + if(result==OV_EREAD) goto seek_error; + if(result<0){ + if(bisect<=begin+1) + end=begin; /* found it */ + else{ + if(bisect==0) goto seek_error; + bisect-=CHUNKSIZE; + if(bisect<=begin)bisect=begin+1; + _seek_helper(vf,bisect); + } + }else{ + ogg_int64_t granulepos=ogg_page_granulepos(&og); + if(granulepos==-1)continue; + if(granuleposoffset; /* raw offset of next page */ + begintime=granulepos; + + if(target-begintime>44100)break; + bisect=begin; /* *not* begin + 1 */ + }else{ + if(bisect<=begin+1) + end=begin; /* found it */ + else{ + if(end==vf->offset){ /* we're pretty close - we'd be stuck in */ + end=result; + bisect-=CHUNKSIZE; /* an endless loop otherwise. */ + if(bisect<=begin)bisect=begin+1; + _seek_helper(vf,bisect); + }else{ + end=result; + endtime=granulepos; + break; + } + } + } + } + } + } + + /* found our page. seek to it, update pcm offset. Easier case than + raw_seek, don't keep packets preceeding granulepos. */ + { + + /* seek */ + _seek_helper(vf,best); + vf->pcm_offset=-1; + + if(_get_next_page(vf,&og,-1)<0){ + ogg_page_release(&og); + return(OV_EOF); /* shouldn't happen */ + } + + if(link!=vf->current_link){ + /* Different link; dump entire decode machine */ + _decode_clear(vf); + + vf->current_link=link; + vf->current_serialno=ogg_page_serialno(&og); + vf->ready_state=STREAMSET; + + }else{ + vorbis_synthesis_restart(&vf->vd); + } + + ogg_stream_reset_serialno(vf->os,vf->current_serialno); + ogg_stream_pagein(vf->os,&og); + + /* pull out all but last packet; the one with granulepos */ + while(1){ + result=ogg_stream_packetpeek(vf->os,&op); + if(result==0){ + /* !!! the packet finishing this page originated on a + preceeding page. Keep fetching previous pages until we + get one with a granulepos or without the 'continued' flag + set. Then just use raw_seek for simplicity. */ + + _seek_helper(vf,best); + + while(1){ + result=_get_prev_page(vf,&og); + if(result<0) goto seek_error; + if(ogg_page_granulepos(&og)>-1 || + !ogg_page_continued(&og)){ + return ov_raw_seek(vf,result); + } + vf->offset=result; + } + } + if(result<0){ + result = OV_EBADPACKET; + goto seek_error; + } + if(op.granulepos!=-1){ + vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2]; + if(vf->pcm_offset<0)vf->pcm_offset=0; + vf->pcm_offset+=total; + break; + }else + result=ogg_stream_packetout(vf->os,NULL); + } + } + } + + /* verify result */ + if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){ + result=OV_EFAULT; + goto seek_error; + } + vf->bittrack=0; + vf->samptrack=0; + + ogg_page_release(&og); + ogg_packet_release(&op); + return(0); + + seek_error: + + ogg_page_release(&og); + ogg_packet_release(&op); + + /* dump machine so we're in a known state */ + vf->pcm_offset=-1; + _decode_clear(vf); + return (int)result; +} + +/* seek to a sample offset relative to the decompressed pcm stream + returns zero on success, nonzero on failure */ + +int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){ + ogg_packet op={0,0,0,0,0,0}; + ogg_page og={0,0,0,0}; + int thisblock,lastblock=0; + int ret=ov_pcm_seek_page(vf,pos); + if(ret<0)return(ret); + _make_decode_ready(vf); + + /* discard leading packets we don't need for the lapping of the + position we want; don't decode them */ + + while(1){ + + int ret=ogg_stream_packetpeek(vf->os,&op); + if(ret>0){ + thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); + if(thisblock<0){ + ogg_stream_packetout(vf->os,NULL); + continue; /* non audio packet */ + } + if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2; + + if(vf->pcm_offset+((thisblock+ + vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break; + + /* remove the packet from packet queue and track its granulepos */ + ogg_stream_packetout(vf->os,NULL); + vorbis_synthesis(&vf->vb,&op,0); /* set up a vb with + only tracking, no + pcm_decode */ + vorbis_synthesis_blockin(&vf->vd,&vf->vb); + + /* end of logical stream case is hard, especially with exact + length positioning. */ + + if(op.granulepos>-1){ + int i; + /* always believe the stream markers */ + vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2]; + if(vf->pcm_offset<0)vf->pcm_offset=0; + for(i=0;icurrent_link;i++) + vf->pcm_offset+=vf->pcmlengths[i*2+1]; + } + + lastblock=thisblock; + + }else{ + if(ret<0 && ret!=OV_HOLE)break; + + /* suck in a new page */ + if(_get_next_page(vf,&og,-1)<0)break; + if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf); + + if(vf->ready_statecurrent_serialno=ogg_page_serialno(&og); + for(link=0;linklinks;link++) + if(vf->serialnos[link]==vf->current_serialno)break; + if(link==vf->links){ + ogg_page_release(&og); + ogg_packet_release(&op); + return(OV_EBADLINK); + } + vf->current_link=link; + + ogg_stream_reset_serialno(vf->os,vf->current_serialno); + vf->ready_state=STREAMSET; + _make_decode_ready(vf); + lastblock=0; + } + + ogg_stream_pagein(vf->os,&og); + } + } + + vf->bittrack=0; + vf->samptrack=0; + /* discard samples until we reach the desired position. Crossing a + logical bitstream boundary with abandon is OK. */ + while(vf->pcm_offsetpcm_offset; + long samples=vorbis_synthesis_pcmout(&vf->vd,NULL); + + if(samples>target)samples=target; + vorbis_synthesis_read(&vf->vd,samples); + vf->pcm_offset+=samples; + + if(samplespcm_offset=ov_pcm_total(vf,-1); /* eof */ + } + + ogg_page_release(&og); + ogg_packet_release(&op); + return 0; +} + +/* seek to a playback time relative to the decompressed pcm stream + returns zero on success, nonzero on failure */ +int ov_time_seek(OggVorbis_File *vf,ogg_int64_t milliseconds){ + /* translate time to PCM position and call ov_pcm_seek */ + + int link=-1; + ogg_int64_t pcm_total=ov_pcm_total(vf,-1); + ogg_int64_t time_total=ov_time_total(vf,-1); + + if(vf->ready_stateseekable)return(OV_ENOSEEK); + if(milliseconds<0 || milliseconds>time_total)return(OV_EINVAL); + + /* which bitstream section does this time offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + pcm_total-=vf->pcmlengths[link*2+1]; + time_total-=ov_time_total(vf,link); + if(milliseconds>=time_total)break; + } + + /* enough information to convert time offset to pcm offset */ + { + ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000; + return(ov_pcm_seek(vf,target)); + } +} + +/* page-granularity version of ov_time_seek + returns zero on success, nonzero on failure */ +int ov_time_seek_page(OggVorbis_File *vf,ogg_int64_t milliseconds){ + /* translate time to PCM position and call ov_pcm_seek */ + + int link=-1; + ogg_int64_t pcm_total=ov_pcm_total(vf,-1); + ogg_int64_t time_total=ov_time_total(vf,-1); + + if(vf->ready_stateseekable)return(OV_ENOSEEK); + if(milliseconds<0 || milliseconds>time_total)return(OV_EINVAL); + + /* which bitstream section does this time offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + pcm_total-=vf->pcmlengths[link*2+1]; + time_total-=ov_time_total(vf,link); + if(milliseconds>=time_total)break; + } + + /* enough information to convert time offset to pcm offset */ + { + ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000; + return(ov_pcm_seek_page(vf,target)); + } +} + +/* tell the current stream offset cursor. Note that seek followed by + tell will likely not give the set offset due to caching */ +ogg_int64_t ov_raw_tell(OggVorbis_File *vf){ + if(vf->ready_stateoffset); +} + +/* return PCM offset (sample) of next PCM sample to be read */ +ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){ + if(vf->ready_statepcm_offset); +} + +/* return time offset (milliseconds) of next PCM sample to be read */ +ogg_int64_t ov_time_tell(OggVorbis_File *vf){ + int link=0; + ogg_int64_t pcm_total=0; + ogg_int64_t time_total=0; + + if(vf->ready_stateseekable){ + pcm_total=ov_pcm_total(vf,-1); + time_total=ov_time_total(vf,-1); + + /* which bitstream section does this time offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + pcm_total-=vf->pcmlengths[link*2+1]; + time_total-=ov_time_total(vf,link); + if(vf->pcm_offset>=pcm_total)break; + } + } + + return(time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi[link].rate); +} + +/* link: -1) return the vorbis_info struct for the bitstream section + currently being decoded + 0-n) to request information for a specific bitstream section + + In the case of a non-seekable bitstream, any call returns the + current bitstream. NULL in the case that the machine is not + initialized */ + +vorbis_info *ov_info(OggVorbis_File *vf,int link){ + if(vf->seekable){ + if(link<0) + if(vf->ready_state>=STREAMSET) + return vf->vi+vf->current_link; + else + return vf->vi; + else + if(link>=vf->links) + return NULL; + else + return vf->vi+link; + }else{ + return vf->vi; + } +} + +/* grr, strong typing, grr, no templates/inheritence, grr */ +vorbis_comment *ov_comment(OggVorbis_File *vf,int link){ + if(vf->seekable){ + if(link<0) + if(vf->ready_state>=STREAMSET) + return vf->vc+vf->current_link; + else + return vf->vc; + else + if(link>=vf->links) + return NULL; + else + return vf->vc+link; + }else{ + return vf->vc; + } +} + +/* up to this point, everything could more or less hide the multiple + logical bitstream nature of chaining from the toplevel application + if the toplevel application didn't particularly care. However, at + the point that we actually read audio back, the multiple-section + nature must surface: Multiple bitstream sections do not necessarily + have to have the same number of channels or sampling rate. + + ov_read returns the sequential logical bitstream number currently + being decoded along with the PCM data in order that the toplevel + application can take action on channel/sample rate changes. This + number will be incremented even for streamed (non-seekable) streams + (for seekable streams, it represents the actual logical bitstream + index within the physical bitstream. Note that the accessor + functions above are aware of this dichotomy). + + input values: buffer) a buffer to hold packed PCM data for return + length) the byte length requested to be placed into buffer + + return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL) + 0) EOF + n) number of bytes of PCM actually returned. The + below works on a packet-by-packet basis, so the + return length is not related to the 'length' passed + in, just guaranteed to fit. + + *section) set to the logical bitstream number */ + +long ov_read(OggVorbis_File *vf,char *buffer,int bytes_req,int *bitstream){ + int i,j; + + ogg_int32_t **pcm; + long samples; + + if(vf->ready_stateready_state==INITSET){ + samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); + if(samples)break; + } + + /* suck in another packet */ + { + int ret=_fetch_and_process_packet(vf,1,1); + if(ret==OV_EOF) + return(0); + if(ret<=0) + return(ret); + } + + } + + if(samples>0){ + + /* yay! proceed to pack data into the byte buffer */ + + long channels=ov_info(vf,-1)->channels; + + if(samples>(bytes_req/(2*channels))) + samples=bytes_req/(2*channels); + + for(i=0;i>9); + dest+=channels; + } + } + + vorbis_synthesis_read(&vf->vd,samples); + vf->pcm_offset+=samples; + if(bitstream)*bitstream=vf->current_link; + return(samples*2*channels); + }else{ + return(samples); + } +} diff --git a/genplus-gx/core/tremor/window.c b/genplus-gx/core/tremor/window.c new file mode 100644 index 0000000000..44a3812213 --- /dev/null +++ b/genplus-gx/core/tremor/window.c @@ -0,0 +1,86 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: window functions + + ********************************************************************/ + +#include +#include +#include "misc.h" +#include "window.h" +#include "window_lookup.h" + +const void *_vorbis_window(int type, int left){ + + switch(type){ + case 0: + + switch(left){ + case 32: + return vwin64; + case 64: + return vwin128; + case 128: + return vwin256; + case 256: + return vwin512; + case 512: + return vwin1024; + case 1024: + return vwin2048; + case 2048: + return vwin4096; + case 4096: + return vwin8192; + default: + return(0); + } + break; + default: + return(0); + } +} + +void _vorbis_apply_window(ogg_int32_t *d,const void *window_p[2], + long *blocksizes, + int lW,int W,int nW){ + + LOOKUP_T *window[2]; + long n=blocksizes[W]; + long ln=blocksizes[lW]; + long rn=blocksizes[nW]; + + long leftbegin=n/4-ln/4; + long leftend=leftbegin+ln/2; + + long rightbegin=n/2+n/4-rn/4; + long rightend=rightbegin+rn/2; + + int i,p; + + window[0]=window_p[0]; + window[1]=window_p[1]; + + for(i=0;i> 5) & 0x7FF; \ + if(bg_name_dirty[name] == 0) \ + { \ + bg_name_list[bg_list_index++] = name; \ + } \ + bg_name_dirty[name] |= (1 << ((addr >> 2) & 7)); \ +} + +/* VDP context */ +uint8 sat[0x400]; /* Internal copy of sprite attribute table */ +uint8 vram[0x10000]; /* Video RAM (64K x 8-bit) */ +uint8 cram[0x80]; /* On-chip color RAM (64 x 9-bit) */ +uint8 vsram[0x80]; /* On-chip vertical scroll RAM (40 x 11-bit) */ +uint8 reg[0x20]; /* Internal VDP registers (23 x 8-bit) */ +uint8 hint_pending; /* 0= Line interrupt is pending */ +uint8 vint_pending; /* 1= Frame interrupt is pending */ +uint16 status; /* VDP status flags */ +uint32 dma_length; /* DMA remaining length */ + +/* Global variables */ +uint16 ntab; /* Name table A base address */ +uint16 ntbb; /* Name table B base address */ +uint16 ntwb; /* Name table W base address */ +uint16 satb; /* Sprite attribute table base address */ +uint16 hscb; /* Horizontal scroll table base address */ +uint8 bg_name_dirty[0x800]; /* 1= This pattern is dirty */ +uint16 bg_name_list[0x800]; /* List of modified pattern indices */ +uint16 bg_list_index; /* # of modified patterns in list */ +uint8 hscroll_mask; /* Horizontal Scrolling line mask */ +uint8 playfield_shift; /* Width of planes A, B (in bits) */ +uint8 playfield_col_mask; /* Playfield column mask */ +uint16 playfield_row_mask; /* Playfield row mask */ +uint16 vscroll; /* Latched vertical scroll value */ +uint8 odd_frame; /* 1: odd field, 0: even field */ +uint8 im2_flag; /* 1= Interlace mode 2 is being used */ +uint8 interlaced; /* 1: Interlaced mode 1 or 2 */ +uint8 vdp_pal; /* 1: PAL , 0: NTSC (default) */ +uint16 v_counter; /* Vertical counter */ +uint16 vc_max; /* Vertical counter overflow value */ +uint16 lines_per_frame; /* PAL: 313 lines, NTSC: 262 lines */ +uint16 max_sprite_pixels; /* Max. sprites pixels per line (parsing & rendering) */ +int32 fifo_write_cnt; /* VDP FIFO write count */ +uint32 fifo_slots; /* VDP FIFO access slot count */ +uint32 hvc_latch; /* latched HV counter */ +const uint8 *hctab; /* pointer to H Counter table */ + +/* Function pointers */ +void (*vdp_68k_data_w)(unsigned int data); +void (*vdp_z80_data_w)(unsigned int data); +unsigned int (*vdp_68k_data_r)(void); +unsigned int (*vdp_z80_data_r)(void); + +/* Function prototypes */ +static void vdp_68k_data_w_m4(unsigned int data); +static void vdp_68k_data_w_m5(unsigned int data); +static unsigned int vdp_68k_data_r_m4(void); +static unsigned int vdp_68k_data_r_m5(void); +static void vdp_z80_data_w_m4(unsigned int data); +static void vdp_z80_data_w_m5(unsigned int data); +static unsigned int vdp_z80_data_r_m4(void); +static unsigned int vdp_z80_data_r_m5(void); +static void vdp_z80_data_w_ms(unsigned int data); +static void vdp_z80_data_w_gg(unsigned int data); +static void vdp_z80_data_w_sg(unsigned int data); +static void vdp_bus_w(unsigned int data); +static void vdp_fifo_update(unsigned int cycles); +static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles); +static void vdp_dma_68k_ext(unsigned int length); +static void vdp_dma_68k_ram(unsigned int length); +static void vdp_dma_68k_io(unsigned int length); +static void vdp_dma_copy(unsigned int length); +static void vdp_dma_fill(unsigned int length); + +/* Tables that define the playfield layout */ +static const uint8 hscroll_mask_table[] = { 0x00, 0x07, 0xF8, 0xFF }; +static const uint8 shift_table[] = { 6, 7, 0, 8 }; +static const uint8 col_mask_table[] = { 0x0F, 0x1F, 0x0F, 0x3F }; +static const uint16 row_mask_table[] = { 0x0FF, 0x1FF, 0x2FF, 0x3FF }; + +static uint8 border; /* Border color index */ +static uint8 pending; /* Pending write flag */ +static uint8 code; /* Code register */ +static uint8 dma_type; /* DMA mode */ +static uint16 addr; /* Address register */ +static uint16 addr_latch; /* Latched A15, A14 of address */ +static uint16 sat_base_mask; /* Base bits of SAT */ +static uint16 sat_addr_mask; /* Index bits of SAT */ +static uint16 dma_src; /* DMA source address */ +static uint32 dma_endCycles; /* 68k cycles to DMA end */ +static int dmafill; /* DMA Fill pending flag */ +static int cached_write; /* 2nd part of 32-bit CTRL port write (Genesis mode) or LSB of CRAM data (Game Gear mode) */ +static uint16 fifo[4]; /* FIFO ring-buffer */ +static int fifo_idx; /* FIFO write index */ +static int fifo_byte_access; /* FIFO byte access flag */ +static uint32 fifo_cycles; /* FIFO next access cycle */ + + /* set Z80 or 68k interrupt lines */ +static void (*set_irq_line)(unsigned int level); +static void (*set_irq_line_delay)(unsigned int level); + +/* Vertical counter overflow values (see hvc.h) */ +static const uint16 vc_table[4][2] = +{ + /* NTSC, PAL */ + {0xDA , 0xF2}, /* Mode 4 (192 lines) */ + {0xEA , 0x102}, /* Mode 5 (224 lines) */ + {0xDA , 0xF2}, /* Mode 4 (192 lines) */ + {0x106, 0x10A} /* Mode 5 (240 lines) */ +}; + +/* DMA Timings (number of access slots per line) */ +static const uint8 dma_timing[2][2] = +{ +/* H32, H40 */ + {16 , 18}, /* active display */ + {167, 205} /* blank display */ +}; + +/* DMA processing functions (set by VDP register 23 high nibble) */ +static void (*const dma_func[16])(unsigned int length) = +{ + /* 0x0-0x3 : DMA from 68k bus $000000-$7FFFFF (external area) */ + vdp_dma_68k_ext,vdp_dma_68k_ext,vdp_dma_68k_ext,vdp_dma_68k_ext, + + /* 0x4-0x7 : DMA from 68k bus $800000-$FFFFFF (internal RAM & I/O) */ + vdp_dma_68k_ram, vdp_dma_68k_io,vdp_dma_68k_ram,vdp_dma_68k_ram, + + /* 0x8-0xB : DMA Fill */ + vdp_dma_fill,vdp_dma_fill,vdp_dma_fill,vdp_dma_fill, + + /* 0xC-0xF : DMA Copy */ + vdp_dma_copy,vdp_dma_copy,vdp_dma_copy,vdp_dma_copy +}; + + +/*--------------------------------------------------------------------------*/ +/* Init, reset, context functions */ +/*--------------------------------------------------------------------------*/ + +void vdp_init(void) +{ + /* PAL/NTSC timings */ + lines_per_frame = vdp_pal ? 313: 262; + + /* CPU interrupt line(s)*/ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* 68k cpu */ + set_irq_line = m68k_set_irq; + set_irq_line_delay = m68k_set_irq_delay; + } + else + { + /* Z80 cpu */ + set_irq_line = z80_set_irq_line; + set_irq_line_delay = z80_set_irq_line; + } +} + +void vdp_reset(void) +{ + int i; + + memset ((char *) sat, 0, sizeof (sat)); + memset ((char *) vram, 0, sizeof (vram)); + memset ((char *) cram, 0, sizeof (cram)); + memset ((char *) vsram, 0, sizeof (vsram)); + memset ((char *) reg, 0, sizeof (reg)); + + addr = 0; + addr_latch = 0; + code = 0; + pending = 0; + border = 0; + hint_pending = 0; + vint_pending = 0; + dmafill = 0; + dma_src = 0; + dma_type = 0; + dma_length = 0; + dma_endCycles = 0; + odd_frame = 0; + im2_flag = 0; + interlaced = 0; + fifo_write_cnt = 0; + fifo_cycles = 0; + fifo_slots = 0; + fifo_idx = 0; + cached_write = -1; + fifo_byte_access = 1; + + ntab = 0; + ntbb = 0; + ntwb = 0; + satb = 0; + hscb = 0; + + vscroll = 0; + + hscroll_mask = 0x00; + playfield_shift = 6; + playfield_col_mask = 0x0F; + playfield_row_mask = 0x0FF; + sat_base_mask = 0xFE00; + sat_addr_mask = 0x01FF; + + /* reset pattern cache changes */ + bg_list_index = 0; + memset ((char *) bg_name_dirty, 0, sizeof (bg_name_dirty)); + memset ((char *) bg_name_list, 0, sizeof (bg_name_list)); + + /* default HVC */ + hvc_latch = 0x10000; + hctab = cycle2hc32; + vc_max = vc_table[0][vdp_pal]; + v_counter = lines_per_frame - 1; + + /* default Window clipping */ + window_clip(0,0); + + /* reset VDP status (FIFO empty flag is set) */ + if (system_hw & SYSTEM_MD) + { + status = vdp_pal | 0x200; + } + else + { + status = 0; + } + + /* default display area */ + bitmap.viewport.w = 256; + bitmap.viewport.h = 192; + bitmap.viewport.ow = 256; + bitmap.viewport.oh = 192; + + /* default sprite pixel width */ + max_sprite_pixels = 256; + + /* default overscan area */ + if ((system_hw == SYSTEM_GG) && !config.gg_extra) + { + /* Display area reduced to 160x144 if overscan is disabled */ + bitmap.viewport.x = (config.overscan & 2) ? 14 : -48; + bitmap.viewport.y = (config.overscan & 1) ? (24 * (vdp_pal + 1)) : -24; + } + else + { + bitmap.viewport.x = (config.overscan & 2) * 7; + bitmap.viewport.y = (config.overscan & 1) * 24 * (vdp_pal + 1); + } + + /* default rendering mode */ + update_bg_pattern_cache = update_bg_pattern_cache_m4; + if (system_hw < SYSTEM_MD) + { + /* Mode 0 */ + render_bg = render_bg_m0; + render_obj = render_obj_tms; + parse_satb = parse_satb_tms; + } + else + { + /* Mode 4 */ + render_bg = render_bg_m4; + render_obj = render_obj_m4; + parse_satb = parse_satb_m4; + } + + /* default 68k bus interface (Mega Drive VDP only) */ + vdp_68k_data_w = vdp_68k_data_w_m4; + vdp_68k_data_r = vdp_68k_data_r_m4; + + /* default Z80 bus interface */ + switch (system_hw) + { + case SYSTEM_SG: + { + /* SG-1000 VDP (TMS99xx) */ + vdp_z80_data_w = vdp_z80_data_w_sg; + vdp_z80_data_r = vdp_z80_data_r_m4; + break; + } + + case SYSTEM_GG: + { + /* Game Gear VDP */ + vdp_z80_data_w = vdp_z80_data_w_gg; + vdp_z80_data_r = vdp_z80_data_r_m4; + break; + } + + case SYSTEM_MARKIII: + case SYSTEM_SMS: + case SYSTEM_SMS2: + case SYSTEM_GGMS: + { + /* Master System or Game Gear (in MS compatibility mode) VDP */ + vdp_z80_data_w = vdp_z80_data_w_ms; + vdp_z80_data_r = vdp_z80_data_r_m4; + break; + } + + default: + { + /* Mega Drive VDP (in MS compatibility mode) */ + vdp_z80_data_w = vdp_z80_data_w_m4; + vdp_z80_data_r = vdp_z80_data_r_m4; + break; + } + } + + /* SG-1000 specific */ + if (system_hw == SYSTEM_SG) + { + /* 16k address decoding by default (Magical Kid Wiz) */ + vdp_reg_w(1, 0x80, 0); + + /* no H-INT on TMS99xx */ + vdp_reg_w(10, 0xFF, 0); + } + + /* Master System specific */ + else if ((system_hw & SYSTEM_SMS) && (!(config.bios & 1) || !(system_bios & SYSTEM_SMS))) + { + /* force registers initialization (only if Master System BIOS is disabled or not loaded) */ + vdp_reg_w(0 , 0x36, 0); + vdp_reg_w(1 , 0x80, 0); + vdp_reg_w(2 , 0xFF, 0); + vdp_reg_w(3 , 0xFF, 0); + vdp_reg_w(4 , 0xFF, 0); + vdp_reg_w(5 , 0xFF, 0); + vdp_reg_w(6 , 0xFF, 0); + vdp_reg_w(10, 0xFF, 0); + + /* Mode 4 */ + render_bg = render_bg_m4; + render_obj = render_obj_m4; + parse_satb = parse_satb_m4; + } + + /* Mega Drive specific */ + else if (((system_hw == SYSTEM_MD) || (system_hw == SYSTEM_MCD)) && (config.bios & 1) && !(system_bios & SYSTEM_MD)) + { + /* force registers initialization (only if TMSS model is emulated and BOOT ROM is not loaded) */ + vdp_reg_w(0 , 0x04, 0); + vdp_reg_w(1 , 0x04, 0); + vdp_reg_w(10, 0xFF, 0); + vdp_reg_w(12, 0x81, 0); + vdp_reg_w(15, 0x02, 0); + } + + /* reset color palette */ + for(i = 0; i < 0x20; i ++) + { + color_update_m4(i, 0x00); + } + color_update_m4(0x40, 0x00); +} + +int vdp_context_save(uint8 *state) +{ + int bufferptr = 0; + + save_param(sat, sizeof(sat)); + save_param(vram, sizeof(vram)); + save_param(cram, sizeof(cram)); + save_param(vsram, sizeof(vsram)); + save_param(reg, sizeof(reg)); + save_param(&addr, sizeof(addr)); + save_param(&addr_latch, sizeof(addr_latch)); + save_param(&code, sizeof(code)); + save_param(&pending, sizeof(pending)); + save_param(&status, sizeof(status)); + save_param(&dmafill, sizeof(dmafill)); + save_param(&fifo_idx, sizeof(fifo_idx)); + save_param(&fifo, sizeof(fifo)); + save_param(&hint_pending, sizeof(hint_pending)); + save_param(&vint_pending, sizeof(vint_pending)); + save_param(&dma_length, sizeof(dma_length)); + save_param(&dma_type, sizeof(dma_type)); + save_param(&dma_src, sizeof(dma_src)); + save_param(&cached_write, sizeof(cached_write)); + return bufferptr; +} + +int vdp_context_load(uint8 *state, uint8 version) +{ + int i, bufferptr = 0; + uint8 temp_reg[0x20]; + + load_param(sat, sizeof(sat)); + load_param(vram, sizeof(vram)); + load_param(cram, sizeof(cram)); + load_param(vsram, sizeof(vsram)); + load_param(temp_reg, sizeof(temp_reg)); + + /* restore VDP registers */ + if (system_hw < SYSTEM_MD) + { + if (system_hw > SYSTEM_SG) + { + for (i=0;i<0x10;i++) + { + pending = 1; + addr_latch = temp_reg[i]; + vdp_sms_ctrl_w(0x80 | i); + } + } + else + { + for (i=0;i<0x08;i++) + { + pending = 1; + addr_latch = temp_reg[i]; + vdp_tms_ctrl_w(0x80 | i); + } + } + } + else + { + for (i=0;i<0x20;i++) + { + vdp_reg_w(i, temp_reg[i], 0); + } + } + + load_param(&addr, sizeof(addr)); + load_param(&addr_latch, sizeof(addr_latch)); + load_param(&code, sizeof(code)); + load_param(&pending, sizeof(pending)); + load_param(&status, sizeof(status)); + + /* 1.7.1 state compatibility */ + if (version < 0x35) + { + uint16 temp; + load_param(&temp, 2); + dmafill = temp >> 8; + temp &= 0xff; + fifo_idx = 0; + fifo[0] = fifo[1] = fifo[2] = fifo[3] = (temp << 8) | temp; + } + else + { + load_param(&dmafill, sizeof(dmafill)); + load_param(&fifo_idx, sizeof(fifo_idx)); + load_param(&fifo, sizeof(fifo)); + } + + load_param(&hint_pending, sizeof(hint_pending)); + load_param(&vint_pending, sizeof(vint_pending)); + load_param(&dma_length, sizeof(dma_length)); + load_param(&dma_type, sizeof(dma_type)); + load_param(&dma_src, sizeof(dma_src)); + load_param(&cached_write, sizeof(cached_write)); + + /* restore FIFO byte access flag */ + fifo_byte_access = ((code & 0x0F) < 0x03); + + /* restore current NTSC/PAL mode */ + if (system_hw & SYSTEM_MD) + { + status = (status & ~1) | vdp_pal; + } + + if (reg[1] & 0x04) + { + /* Mode 5 */ + bg_list_index = 0x800; + + /* reinitialize palette */ + color_update_m5(0, *(uint16 *)&cram[border << 1]); + for(i = 1; i < 0x40; i++) + { + color_update_m5(i, *(uint16 *)&cram[i << 1]); + } + } + else + { + /* Modes 0,1,2,3,4 */ + bg_list_index = 0x200; + + /* reinitialize palette */ + for(i = 0; i < 0x20; i ++) + { + color_update_m4(i, *(uint16 *)&cram[i << 1]); + } + color_update_m4(0x40, *(uint16 *)&cram[(0x10 | (border & 0x0F)) << 1]); + } + + /* invalidate cache */ + for (i=0;i VDP 32-cell Active 16 + Blanking 167 + 40-cell Active 18 + Blanking 205 + VRAM Fill 32-cell Active 15 + Blanking 166 + 40-cell Active 17 + Blanking 204 + VRAM Copy 32-cell Active 8 + Blanking 83 + 40-cell Active 9 + Blanking 102 + + 'Active' is the active display period, 'Blanking' is either the vertical + blanking period or when the display is forcibly blanked via register #1. + + The above transfer counts are all in bytes, unless the destination is + CRAM or VSRAM for a 68K > VDP transfer, in which case it is in words. + */ + unsigned int rate = dma_timing[(status & 8) || !(reg[1] & 0x40)][reg[12] & 1]; + + /* Adjust for 68k bus DMA to VRAM (one word = 2 access) or DMA Copy (one read + one write = 2 access) */ + rate = rate >> (dma_type & 1); + + /* Remaining DMA cycles */ + if (status & 8) + { + /* Process DMA until the end of VBLANK */ + /* NOTE: DMA timings can not change during VBLANK because active display width cannot be modified. */ + /* Indeed, writing VDP registers during DMA is either impossible (when doing DMA from 68k bus, CPU */ + /* is locked) or will abort DMA operation (in case of DMA Fill or Copy). */ + dma_cycles = (lines_per_frame * MCYCLES_PER_LINE) - cycles; + } + else + { + /* Process DMA until the end of current line */ + dma_cycles = (mcycles_vdp + MCYCLES_PER_LINE) - cycles; + } + + /* Remaining DMA bytes for that line */ + dma_bytes = (dma_cycles * rate) / MCYCLES_PER_LINE; + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] DMA type %d (%d access/line)(%d cycles left)-> %d access (%d remaining) (%x)\n", v_counter, m68k.cycles/MCYCLES_PER_LINE, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE,dma_type, rate, dma_cycles, dma_bytes, dma_length, m68k_get_reg(M68K_REG_PC)); +#endif + + /* Check if DMA can be finished before the end of current line */ + if (dma_length < dma_bytes) + { + /* Adjust remaining DMA bytes */ + dma_bytes = dma_length; + dma_cycles = (dma_bytes * MCYCLES_PER_LINE) / rate; + } + + /* Update DMA timings */ + if (dma_type < 2) + { + /* 68K is frozen during DMA from 68k bus */ + m68k.cycles = cycles + dma_cycles; +#ifdef LOGVDP + error("-->CPU frozen for %d cycles\n", dma_cycles); +#endif + } + else + { + /* Set DMA Busy flag */ + status |= 0x02; + + /* 68K is still running, set DMA end cycle */ + dma_endCycles = cycles + dma_cycles; +#ifdef LOGVDP + error("-->DMA ends in %d cycles\n", dma_cycles); +#endif + } + + /* Process DMA */ + if (dma_bytes > 0) + { + /* Update DMA length */ + dma_length -= dma_bytes; + + /* Process DMA operation */ + dma_func[reg[23] >> 4](dma_bytes); + + /* Check if DMA is finished */ + if (!dma_length) + { + /* DMA source address registers are incremented during DMA (even DMA Fill) */ + uint16 end = reg[21] + (reg[22] << 8) + reg[19] + (reg[20] << 8); + reg[21] = end & 0xff; + reg[22] = end >> 8; + + /* DMA length registers are decremented during DMA */ + reg[19] = reg[20] = 0; + + /* perform cached write, if any */ + if (cached_write >= 0) + { + vdp_68k_ctrl_w(cached_write); + cached_write = -1; + } + } + } +} + + +/*--------------------------------------------------------------------------*/ +/* Control port access functions */ +/*--------------------------------------------------------------------------*/ + +void vdp_68k_ctrl_w(unsigned int data) +{ + /* Check pending flag */ + if (pending == 0) + { + /* A single long word write instruction could have started DMA with the first word */ + if (dma_length) + { + /* 68k is frozen during 68k bus DMA */ + /* Second word should be written after DMA completion */ + /* See Formula One & Kawasaki Superbike Challenge */ + if (dma_type < 2) + { + /* Latch second control word for later */ + cached_write = data; + return; + } + } + + /* Check CD0-CD1 bits */ + if ((data & 0xC000) == 0x8000) + { + /* VDP register write */ + vdp_reg_w((data >> 8) & 0x1F, data & 0xFF, m68k.cycles); + } + else + { + /* Set pending flag (Mode 5 only) */ + pending = reg[1] & 4; + } + + /* Update address and code registers */ + addr = addr_latch | (data & 0x3FFF); + code = ((code & 0x3C) | ((data >> 14) & 0x03)); + } + else + { + /* Clear pending flag */ + pending = 0; + + /* Save address bits A15 and A14 */ + addr_latch = (data & 3) << 14; + + /* Update address and code registers */ + addr = addr_latch | (addr & 0x3FFF); + code = ((code & 0x03) | ((data >> 2) & 0x3C)); + + /* Detect DMA operation (CD5 bit set) */ + if (code & 0x20) + { + /* DMA must be enabled */ + if (reg[1] & 0x10) + { + /* DMA type */ + switch (reg[23] >> 6) + { + case 2: + { + /* DMA Fill */ + dma_type = 2; + + /* DMA is pending until next DATA port write */ + dmafill = 1; + + /* Set DMA Busy flag */ + status |= 0x02; + + /* DMA end cycle is not initialized yet (this prevents DMA Busy flag from being cleared on VDP status read) */ + dma_endCycles = 0xffffffff; + break; + } + + case 3: + { + /* DMA Copy */ + dma_type = 3; + + /* DMA length */ + dma_length = (reg[20] << 8) | reg[19]; + + /* Zero DMA length (pre-decrementing counter) */ + if (!dma_length) + { + dma_length = 0x10000; + } + + /* DMA source address */ + dma_src = (reg[22] << 8) | reg[21]; + + /* Trigger DMA */ + vdp_dma_update(m68k.cycles); + break; + } + + default: + { + /* DMA from 68k bus */ + dma_type = (code & 0x06) ? 0 : 1; + + /* DMA length */ + dma_length = (reg[20] << 8) | reg[19]; + + /* Zero DMA length (pre-decrementing counter) */ + if (!dma_length) + { + dma_length = 0x10000; + } + + /* DMA source address */ + dma_src = (reg[22] << 8) | reg[21]; + + /* Transfer from SVP ROM/RAM ($000000-$3fffff) or CD Word-RAM ($200000-$3fffff/$600000-$7fffff) */ + if (((system_hw == SYSTEM_MCD) && ((reg[23] & 0x70) == ((scd.cartridge.boot >> 1) + 0x10))) || (svp && !(reg[23] & 0x60))) + { + /* source data is available with one cycle delay, i.e first word written by VDP is */ + /* previous data being held on 68k bus at that time, then source words are written */ + /* normally to VDP RAM, with only last source word being ignored */ + addr += reg[15]; + dma_length--; + } + + /* Trigger DMA */ + vdp_dma_update(m68k.cycles); + break; + } + } + } + } + } + + /* + FIFO emulation (Chaos Engine/Soldier of Fortune, Double Clutch, Sol Deace) + -------------------------------------------------------------------------- + Each VRAM access is byte wide, so one VRAM write (word) need two slot access. + + NOTE: Invalid code 0x02 (register write) should not behave the same as VRAM + access, i.e data is ignored and only one access slot is used for each word, + BUT a few games ("Clue", "Microcosm") which accidentally corrupt code value + will have issues when emulating FIFO timings. They likely work fine on real + hardware because of periodical 68k wait-states which have been observed and + would naturaly add some delay between writes. Until those wait-states are + accurately measured and emulated, delay is forced when invalid code value + is being used. + */ + fifo_byte_access = ((code & 0x0F) <= 0x02); +} + +/* Mega Drive VDP control port specific (MS compatibility mode) */ +void vdp_z80_ctrl_w(unsigned int data) +{ + switch (pending) + { + case 0: + { + /* Latch LSB */ + addr_latch = data; + + /* Set LSB pending flag */ + pending = 1; + return; + } + + case 1: + { + /* Update address and code registers */ + addr = (addr & 0xC000) | ((data & 0x3F) << 8) | addr_latch ; + code = ((code & 0x3C) | ((data >> 6) & 0x03)); + + if ((code & 0x03) == 0x02) + { + /* VDP register write */ + vdp_reg_w(data & 0x1F, addr_latch, Z80.cycles); + + /* Clear pending flag */ + pending = 0; + return; + } + + /* Set Mode 5 pending flag */ + pending = (reg[1] & 4) >> 1; + + if (!pending && !(code & 0x03)) + { + /* Process VRAM read */ + fifo[0] = vram[addr & 0x3FFF]; + + /* Increment address register */ + addr += (reg[15] + 1); + } + return; + } + + case 2: + { + /* Latch LSB */ + addr_latch = data; + + /* Set LSB pending flag */ + pending = 3; + return; + } + + case 3: + { + /* Clear pending flag */ + pending = 0; + + /* Update address and code registers */ + addr = ((addr_latch & 3) << 14) | (addr & 0x3FFF); + code = ((code & 0x03) | ((addr_latch >> 2) & 0x3C)); + + /* Detect DMA operation (CD5 bit set) */ + if (code & 0x20) + { + /* DMA should be enabled */ + if (reg[1] & 0x10) + { + /* DMA type */ + switch (reg[23] >> 6) + { + case 2: + { + /* DMA Fill will be triggered by next write to DATA port */ + dmafill = 1; + + /* Set DMA Busy flag */ + status |= 0x02; + + /* DMA end cycle is not initialized yet (this prevents DMA Busy flag from being cleared on VDP status read) */ + dma_endCycles = 0xffffffff; + break; + } + + case 3: + { + /* DMA copy */ + dma_type = 3; + + /* DMA length */ + dma_length = (reg[20] << 8) | reg[19]; + + /* Zero DMA length (pre-decrementing counter) */ + if (!dma_length) + { + dma_length = 0x10000; + } + + /* DMA source address */ + dma_src = (reg[22] << 8) | reg[21]; + + /* Trigger DMA */ + vdp_dma_update(Z80.cycles); + break; + } + + default: + { + /* DMA from 68k bus does not work when Z80 is in control */ + break; + } + } + } + } + } + return; + } +} + +/* Master System & Game Gear VDP control port specific */ +void vdp_sms_ctrl_w(unsigned int data) +{ + if(pending == 0) + { + /* Update address register LSB */ + addr = (addr & 0x3F00) | (data & 0xFF); + + /* Latch LSB */ + addr_latch = data; + + /* Set LSB pending flag */ + pending = 1; + } + else + { + /* Update address and code registers */ + code = (data >> 6) & 3; + addr = (data << 8 | addr_latch) & 0x3FFF; + + /* Clear pending flag */ + pending = 0; + + if (code == 0) + { + /* Process VRAM read */ + fifo[0] = vram[addr & 0x3FFF]; + + /* Increment address register */ + addr = (addr + 1) & 0x3FFF; + return; + } + + if (code == 2) + { + /* Save current VDP mode */ + int mode, prev = (reg[0] & 0x06) | (reg[1] & 0x18); + + /* Write VDP register 0-15 */ + vdp_reg_w(data & 0x0F, addr_latch, Z80.cycles); + + /* Check VDP mode changes */ + mode = (reg[0] & 0x06) | (reg[1] & 0x18); + prev ^= mode; + + if (prev) + { + /* Check for extended modes */ + if (system_hw > SYSTEM_SMS) + { + int height; + + if (mode == 0x0E) /* M1=0,M2=1,M3=1,M4=1 */ + { + /* Mode 4 extended (240 lines) */ + height = 240; + + /* Update vertical counter max value */ + vc_max = vc_table[3][vdp_pal]; + } + else if (mode == 0x16) /* M1=1,M2=1,M3=0,M4=1 */ + { + /* Mode 4 extended (224 lines) */ + height = 224; + + /* Update vertical counter max value */ + vc_max = vc_table[1][vdp_pal]; + } + else + { + /* Mode 4 default (224 lines) */ + height = 192; + + /* Default vertical counter max value */ + vc_max = vc_table[0][vdp_pal]; + } + + if (height != bitmap.viewport.h) + { + if (status & 8) + { + /* viewport changes should be applied on next frame */ + bitmap.viewport.changed |= 2; + } + else + { + /* update active display */ + bitmap.viewport.h = height; + + /* update vertical overscan */ + if (config.overscan & 1) + { + bitmap.viewport.y = (240 + 48*vdp_pal - height) >> 1; + } + else + { + if ((system_hw == SYSTEM_GG) && !config.gg_extra) + { + /* Display area reduced to 160x144 */ + bitmap.viewport.y = (144 - height) / 2; + } + else + { + bitmap.viewport.y = 0; + } + } + } + } + } + + /* Rendering mode */ + switch (mode) + { + case 0x00: /* Graphics I */ + { + render_bg = render_bg_m0; + break; + } + + case 0x10: /* Text */ + { + render_bg = render_bg_m1; + break; + } + + case 0x02: /* Graphics II */ + { + render_bg = render_bg_m2; + break; + } + + case 0x12: /* Text (Extended PG) */ + { + render_bg = render_bg_m1x; + break; + } + + case 0x08: /* Multicolor */ + { + render_bg = render_bg_m3; + break; + } + + case 0x18: /* Invalid (1+3) */ + { + render_bg = render_bg_inv; + break; + } + + case 0x0A: /* Multicolor (Extended PG) */ + { + render_bg = render_bg_m3x; + break; + } + + case 0x1A: /* Invalid (1+2+3) */ + { + render_bg = render_bg_inv; + break; + } + + default: /* Mode 4 */ + { + render_bg = render_bg_m4; + break; + } + } + + /* Mode switching */ + if (prev & 0x04) + { + int i; + + if (mode & 0x04) + { + /* Mode 4 sprites */ + parse_satb = parse_satb_m4; + render_obj = render_obj_m4; + + /* force BG cache update*/ + bg_list_index = 0x200; + } + else + { + /* TMS-mode sprites */ + parse_satb = parse_satb_tms; + render_obj = render_obj_tms; + + /* BG cache is not used */ + bg_list_index = 0; + } + + /* reinitialize palette */ + for(i = 0; i < 0x20; i ++) + { + color_update_m4(i, *(uint16 *)&cram[i << 1]); + } + color_update_m4(0x40, *(uint16 *)&cram[(0x10 | (border & 0x0F)) << 1]); + } + } + } + } +} + +/* SG-1000 VDP (TMS99xx) control port specific */ +void vdp_tms_ctrl_w(unsigned int data) +{ + if(pending == 0) + { + /* Latch LSB */ + addr_latch = data; + + /* Set LSB pending flag */ + pending = 1; + } + else + { + /* Update address and code registers */ + code = (data >> 6) & 3; + addr = (data << 8 | addr_latch) & 0x3FFF; + + /* Clear pending flag */ + pending = 0; + + if (code == 0) + { + /* Process VRAM read */ + fifo[0] = vram[addr & 0x3FFF]; + + /* Increment address register */ + addr = (addr + 1) & 0x3FFF; + return; + } + + if (code & 2) + { + /* VDP register index (0-7) */ + data &= 0x07; + + /* Write VDP register */ + vdp_reg_w(data, addr_latch, Z80.cycles); + + /* Check VDP mode changes */ + if (data < 2) + { + int mode = (reg[0] & 0x02) | (reg[1] & 0x18); + + /* Rendering mode */ + switch (mode) + { + case 0x00: /* Graphics I */ + { + render_bg = render_bg_m0; + break; + } + + case 0x10: /* Text */ + { + render_bg = render_bg_m1; + break; + } + + case 0x02: /* Graphics II */ + { + render_bg = render_bg_m2; + break; + } + + case 0x12: /* Text (Extended PG) */ + { + render_bg = render_bg_m1x; + break; + } + + case 0x08: /* Multicolor */ + { + render_bg = render_bg_m3; + break; + } + + case 0x18: /* Invalid (1+3) */ + { + render_bg = render_bg_inv; + break; + } + + case 0x0A: /* Multicolor (Extended PG) */ + { + render_bg = render_bg_m3x; + break; + } + + case 0x1A: /* Invalid (1+2+3) */ + { + render_bg = render_bg_inv; + break; + } + } + } + } + } +} + + /* + * Status register + * + * Bits + * 0 NTSC(0)/PAL(1) + * 1 DMA Busy + * 2 During HBlank + * 3 During VBlank + * 4 0:1 even:odd field (interlaced modes only) + * 5 Sprite collision + * 6 Too many sprites per line + * 7 v interrupt occurred + * 8 Write FIFO full + * 9 Write FIFO empty + * 10 - 15 Open Bus + */ +unsigned int vdp_68k_ctrl_r(unsigned int cycles) +{ + unsigned int temp; + + /* Update FIFO status flags if not empty */ + if (fifo_write_cnt) + { + vdp_fifo_update(cycles); + } + + /* Check if DMA Busy flag is set */ + if (status & 2) + { + /* Check if DMA is finished */ + if (!dma_length && (cycles >= dma_endCycles)) + { + /* Clear DMA Busy flag */ + status &= 0xFFFD; + } + } + + /* Return VDP status */ + temp = status; + + /* Clear pending flag */ + pending = 0; + + /* Clear SOVR & SCOL flags */ + status &= 0xFF9F; + + /* Display OFF: VBLANK flag is set */ + if (!(reg[1] & 0x40)) + { + temp |= 0x08; + } + + /* HBLANK flag (Sonic 3 and Sonic 2 "VS Modes", Lemmings 2, Mega Turrican, V.R Troopers, Gouketsuji Ichizoku,...) */ + /* NB: this is not 100% accurate and need to be verified on real hardware */ + if ((cycles % MCYCLES_PER_LINE) < 588) + { + temp |= 0x04; + } + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VDP 68k status read -> 0x%x (0x%x) (%x)\n", v_counter, cycles/MCYCLES_PER_LINE-1, cycles, cycles%MCYCLES_PER_LINE, temp, status, m68k_get_reg(M68K_REG_PC)); +#endif + return (temp); +} + +unsigned int vdp_z80_ctrl_r(unsigned int cycles) +{ + unsigned int temp; + + /* Cycle-accurate SOVR & VINT flags */ + int line = (lines_per_frame + (cycles / MCYCLES_PER_LINE) - 1) % lines_per_frame; + + /* Check if DMA busy flag is set (Mega Drive VDP specific) */ + if (status & 2) + { + /* Check if DMA is finished */ + if (!dma_length && (cycles >= dma_endCycles)) + { + /* Clear DMA Busy flag */ + status &= 0xFD; + } + } + + /* Check if we are already on next line */ + if (line > v_counter) + { + v_counter = line; + if (line == (bitmap.viewport.h + 1)) + { + /* set VINT flag (immediately cleared after) */ + status |= 0x80; + } + else if ((line >= 0) && (line < bitmap.viewport.h) && !(work_ram[0x1ffb] & cart.special)) + { + /* render next line to check sprites overflow & collision */ + render_line(line); + } + } + + /* Return VDP status */ + temp = status; + + /* Clear pending flag */ + pending = 0; + + /* Clear VINT, SOVR & SCOL flags */ + status &= 0xFF1F; + + /* Mega Drive VDP specific */ + if (system_hw & SYSTEM_MD) + { + /* Display OFF: VBLANK flag is set */ + if (!(reg[1] & 0x40)) + { + temp |= 0x08; + } + + /* HBLANK flag */ + if ((cycles % MCYCLES_PER_LINE) < 588) + { + temp |= 0x04; + } + } + else if (reg[0] & 0x04) + { + /* Mode 4 unused bits (fixes PGA Tour Golf) */ + temp |= 0x1F; + } + + /* Cycle-accurate SCOL flag */ + if ((temp & 0x20) && (line == (spr_col >> 8))) + { + if (system_hw & SYSTEM_MD) + { + /* COL flag is set at HCount 0xFF on MD */ + if ((cycles % MCYCLES_PER_LINE) < 105) + { + status |= 0x20; + temp &= ~0x20; + } + } + else + { + /* COL flag is set at the pixel it occurs */ + uint8 hc = hctab[(cycles + SMS_CYCLE_OFFSET + 15) % MCYCLES_PER_LINE]; + if ((hc < (spr_col & 0xff)) || (hc > 0xf3)) + { + status |= 0x20; + temp &= ~0x20; + } + } + } + + /* Clear HINT & VINT pending flags */ + hint_pending = vint_pending = 0; + + /* Clear Z80 interrupt */ + Z80.irq_state = CLEAR_LINE; + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VDP Z80 status read -> 0x%x (0x%x) (%x)\n", v_counter, cycles/MCYCLES_PER_LINE-1, cycles, cycles%MCYCLES_PER_LINE, temp, status, Z80.pc.w.l); +#endif + return (temp); +} + +/*--------------------------------------------------------------------------*/ +/* HV Counters */ +/*--------------------------------------------------------------------------*/ + +unsigned int vdp_hvc_r(unsigned int cycles) +{ + int vc; + unsigned int data = hvc_latch; + + /* Check if HVC latch is enabled */ + if (data) + { + /* Mode 5: HV-counters are frozen (cf. lightgun games, Sunset Riders logo) */ + if (reg[1] & 0x04) + { +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] HVC latch read -> 0x%x (%x)\n", v_counter, (cycles/MCYCLES_PER_LINE-1)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, data & 0xffff, m68k_get_reg(M68K_REG_PC)); +#endif + /* return latched HVC value */ + return (data & 0xffff); + } + else + { + /* Mode 4: by default, V-counter runs normally & H counter is frozen */ + data &= 0xff; + } + } + else + { + /* Cycle-accurate H-Counter (Striker, Mickey Mania, Skitchin, Road Rash I,II,III, Sonic 3D Blast...) */ + data = hctab[cycles % MCYCLES_PER_LINE]; + } + + /* Cycle-accurate V-Counter (cycle counter starts from line -1) */ + vc = (cycles / MCYCLES_PER_LINE) - 1; + + /* V-Counter overflow */ + if (vc > vc_max) + { + vc -= lines_per_frame; + } + + /* Interlaced modes */ + if (interlaced) + { + /* Interlace mode 2 (Sonic the Hedgehog 2, Combat Cars) */ + vc <<= im2_flag; + + /* Replace bit 0 with bit 8 */ + vc = (vc & ~1) | ((vc >> 8) & 1); + } + + /* return H-Counter in LSB & V-Counter in MSB */ + data |= ((vc & 0xff) << 8); + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] HVC read -> 0x%x (%x)\n", v_counter, (cycles/MCYCLES_PER_LINE-1)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, data, m68k_get_reg(M68K_REG_PC)); +#endif + return (data); +} + + +/*--------------------------------------------------------------------------*/ +/* Test registers */ +/*--------------------------------------------------------------------------*/ + +void vdp_test_w(unsigned int data) +{ +#ifdef LOGERROR + error("Unused VDP Write 0x%x (%08x)\n", data, m68k_get_reg(M68K_REG_PC)); +#endif +} + + +/*--------------------------------------------------------------------------*/ +/* 68k interrupt handler (TODO: check how interrupts are handled in Mode 4) */ +/*--------------------------------------------------------------------------*/ + +int vdp_68k_irq_ack(int int_level) +{ +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] INT Level %d ack (%x)\n", v_counter, m68k.cycles/MCYCLES_PER_LINE-1, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE,int_level, m68k_get_reg(M68K_REG_PC)); +#endif + + /* VINT has higher priority (Fatal Rewind) */ + if (vint_pending & reg[1]) + { +#ifdef LOGVDP + error("---> VINT cleared\n"); +#endif + + /* Clear VINT pending flag */ + vint_pending = 0; + status &= ~0x80; + + /* Update IRQ status */ + if (hint_pending & reg[0]) + { + m68k_set_irq(4); + } + else + { + m68k_set_irq(0); + } + } + else + { +#ifdef LOGVDP + error("---> HINT cleared\n"); +#endif + + /* Clear HINT pending flag */ + hint_pending = 0; + + /* Update IRQ status */ + m68k_set_irq(0); + } + + return M68K_INT_ACK_AUTOVECTOR; +} + + +/*--------------------------------------------------------------------------*/ +/* VDP registers update function */ +/*--------------------------------------------------------------------------*/ + +static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles) +{ +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VDP register %d write -> 0x%x (%x)\n", v_counter, cycles/MCYCLES_PER_LINE-1, cycles, cycles%MCYCLES_PER_LINE, r, d, m68k_get_reg(M68K_REG_PC)); +#endif + + /* VDP registers #11 to #23 cannot be updated in Mode 4 (Captain Planet & Avengers, Bass Master Classic Pro Edition) */ + if (!(reg[1] & 4) && (r > 10)) + { + return; + } + + switch(r) + { + case 0: /* CTRL #1 */ + { + /* Look for changed bits */ + r = d ^ reg[0]; + reg[0] = d; + + /* Line Interrupt */ + if ((r & 0x10) && hint_pending) + { + /* Update IRQ status */ + if (vint_pending & reg[1]) + { + set_irq_line(6); + } + else if (d & 0x10) + { + set_irq_line_delay(4); + } + else + { + set_irq_line(0); + } + } + + /* Palette selection */ + if (r & 0x04) + { + /* Mega Drive VDP only */ + if (system_hw & SYSTEM_MD) + { + /* Reset color palette */ + int i; + if (reg[1] & 0x04) + { + /* Mode 5 */ + color_update_m5(0x00, *(uint16 *)&cram[border << 1]); + for (i = 1; i < 0x40; i++) + { + color_update_m5(i, *(uint16 *)&cram[i << 1]); + } + } + else + { + /* Mode 4 */ + for (i = 0; i < 0x20; i++) + { + color_update_m4(i, *(uint16 *)&cram[i << 1]); + } + color_update_m4(0x40, *(uint16 *)&cram[(0x10 | (border & 0x0F)) << 1]); + } + } + } + + /* HVC latch (Sunset Riders, Lightgun games) */ + if (r & 0x02) + { + /* Mega Drive VDP only */ + if (system_hw & SYSTEM_MD) + { + /* Mode 5 only */ + if (reg[1] & 0x04) + { + if (d & 0x02) + { + /* Latch current HVC */ + hvc_latch = vdp_hvc_r(cycles) | 0x10000; + } + else + { + /* Free-running HVC */ + hvc_latch = 0; + } + } + } + } + break; + } + + case 1: /* CTRL #2 */ + { + /* Look for changed bits */ + r = d ^ reg[1]; + reg[1] = d; + + /* Display status (modified during active display) */ + if ((r & 0x40) && (v_counter < bitmap.viewport.h)) + { + /* Cycle offset vs HBLANK */ + int offset = cycles - mcycles_vdp; + if (offset <= 860) + { + /* Sprite rendering is limited if display was disabled during HBLANK (Mickey Mania 3d level, Overdrive Demo) */ + if (d & 0x40) + { + /* NB: This is not 100% accurate. On real hardware, the maximal number of rendered sprites pixels */ + /* for the current line (normally 256 or 320 pixels) but also the maximal number of pre-processed */ + /* sprites for the next line (normally 64 or 80 sprites) are both reduced depending on the amount */ + /* of cycles spent with display disabled. Here we only reduce them by a fixed amount when display */ + /* has been reenabled after a specific point within HBLANK. */ + if (offset > 360) + { + max_sprite_pixels = 128; + } + } + + /* Redraw entire line (Legend of Galahad, Lemmings 2, Formula One, Kawasaki Super Bike, Deadly Moves,...) */ + render_line(v_counter); + + /* Restore default */ + max_sprite_pixels = 256 + ((reg[12] & 1) << 6); + } + else if (system_hw & SYSTEM_MD) + { + /* Active pixel offset */ + if (reg[12] & 1) + { + /* dot clock = MCLK / 8 */ + offset = ((offset - 860) / 8) + 16; + } + else + { + /* dot clock = MCLK / 10 */ + offset = ((offset - 860) / 10) + 16; + } + + /* Line is partially blanked (Nigel Mansell's World Championship Racing , Ren & Stimpy Show, ...) */ + if (offset < bitmap.viewport.w) + { + if (d & 0x40) + { + render_line(v_counter); + blank_line(v_counter, 0, offset); + } + else + { + blank_line(v_counter, offset, bitmap.viewport.w - offset); + } + } + } + } + + /* Frame Interrupt */ + if ((r & 0x20) && vint_pending) + { + /* Update IRQ status */ + if (d & 0x20) + { + set_irq_line_delay(6); + } + else if (hint_pending & reg[0]) + { + set_irq_line(4); + } + else + { + set_irq_line(0); + } + } + + /* Active display height */ + if (r & 0x08) + { + /* Mega Drive VDP only */ + if (system_hw & SYSTEM_MD) + { + /* Mode 5 only */ + if (d & 0x04) + { + /* Changes should be applied on next frame */ + bitmap.viewport.changed |= 2; + + /* Update vertical counter max value */ + vc_max = vc_table[(d >> 2) & 3][vdp_pal]; + } + } + } + + /* Rendering mode */ + if (r & 0x04) + { + /* Mega Drive VDP only */ + if (system_hw & SYSTEM_MD) + { + int i; + if (d & 0x04) + { + /* Mode 5 rendering */ + parse_satb = parse_satb_m5; + update_bg_pattern_cache = update_bg_pattern_cache_m5; + if (im2_flag) + { + render_bg = (reg[11] & 0x04) ? render_bg_m5_im2_vs : render_bg_m5_im2; + render_obj = (reg[12] & 0x08) ? render_obj_m5_im2_ste : render_obj_m5_im2; + } + else + { + render_bg = (reg[11] & 0x04) ? render_bg_m5_vs : render_bg_m5; + render_obj = (reg[12] & 0x08) ? render_obj_m5_ste : render_obj_m5; + } + + /* Reset color palette */ + color_update_m5(0x00, *(uint16 *)&cram[border << 1]); + for (i = 1; i < 0x40; i++) + { + color_update_m5(i, *(uint16 *)&cram[i << 1]); + } + + /* Mode 5 bus access */ + vdp_68k_data_w = vdp_68k_data_w_m5; + vdp_z80_data_w = vdp_z80_data_w_m5; + vdp_68k_data_r = vdp_68k_data_r_m5; + vdp_z80_data_r = vdp_z80_data_r_m5; + + /* Change display height */ + if (status & 8) + { + /* viewport changes should be applied on next frame */ + bitmap.viewport.changed |= 2; + } + else + { + /* Update current frame active display height */ + bitmap.viewport.h = 224 + ((d & 8) << 1); + bitmap.viewport.y = (config.overscan & 1) * (8 - (d & 8) + 24*vdp_pal); + } + + /* Clear HVC latched value */ + hvc_latch = 0; + + /* Check if HVC latch bit is set */ + if (reg[0] & 0x02) + { + /* Latch current HVC */ + hvc_latch = vdp_hvc_r(cycles) | 0x10000; + } + + /* max tiles to invalidate */ + bg_list_index = 0x800; + } + else + { + /* Mode 4 rendering */ + parse_satb = parse_satb_m4; + update_bg_pattern_cache = update_bg_pattern_cache_m4; + render_bg = render_bg_m4; + render_obj = render_obj_m4; + + /* Reset color palette */ + for (i = 0; i < 0x20; i++) + { + color_update_m4(i, *(uint16 *)&cram[i << 1]); + } + color_update_m4(0x40, *(uint16 *)&cram[(0x10 | (border & 0x0F)) << 1]); + + /* Mode 4 bus access */ + vdp_68k_data_w = vdp_68k_data_w_m4; + vdp_z80_data_w = vdp_z80_data_w_m4; + vdp_68k_data_r = vdp_68k_data_r_m4; + vdp_z80_data_r = vdp_z80_data_r_m4; + + if (status & 8) + { + /* viewport changes should be applied on next frame */ + bitmap.viewport.changed |= 2; + } + else + { + /* Update current frame active display */ + bitmap.viewport.h = 192; + bitmap.viewport.y = (config.overscan & 1) * 24 * (vdp_pal + 1); + } + + /* Latch current HVC */ + hvc_latch = vdp_hvc_r(cycles) | 0x10000; + + /* max tiles to invalidate */ + bg_list_index = 0x200; + } + + /* Invalidate pattern cache */ + for (i=0;i> 2) & 3][vdp_pal]; + } + else + { + /* No effect (cleared to avoid mode 5 detection elsewhere) */ + reg[1] &= ~0x04; + } + } + break; + } + + case 2: /* Plane A Name Table Base */ + { + reg[2] = d; + ntab = (d << 10) & 0xE000; + + /* Plane A Name Table Base changed during HBLANK */ + if ((v_counter < bitmap.viewport.h) && (reg[1] & 0x40) && (cycles <= (mcycles_vdp + 860))) + { + /* render entire line */ + render_line(v_counter); + } + break; + } + + case 3: /* Window Plane Name Table Base */ + { + reg[3] = d; + if (reg[12] & 0x01) + { + ntwb = (d << 10) & 0xF000; + } + else + { + ntwb = (d << 10) & 0xF800; + } + + /* Window Plane Name Table Base changed during HBLANK */ + if ((v_counter < bitmap.viewport.h) && (reg[1] & 0x40) && (cycles <= (mcycles_vdp + 860))) + { + /* render entire line */ + render_line(v_counter); + } + break; + } + + case 4: /* Plane B Name Table Base */ + { + reg[4] = d; + ntbb = (d << 13) & 0xE000; + + /* Plane B Name Table Base changed during HBLANK (Adventures of Batman & Robin) */ + if ((v_counter < bitmap.viewport.h) && (reg[1] & 0x40) && (cycles <= (mcycles_vdp + 860))) + { + /* render entire line */ + render_line(v_counter); + } + + break; + } + + case 5: /* Sprite Attribute Table Base */ + { + reg[5] = d; + satb = (d << 9) & sat_base_mask; + break; + } + + case 7: /* Backdrop color */ + { + reg[7] = d; + + /* Check if backdrop color changed */ + d &= 0x3F; + + if (d != border) + { + /* Update backdrop color */ + border = d; + + /* Reset palette entry */ + if (reg[1] & 4) + { + /* Mode 5 */ + color_update_m5(0x00, *(uint16 *)&cram[d << 1]); + } + else + { + /* Mode 4 */ + color_update_m4(0x40, *(uint16 *)&cram[(0x10 | (d & 0x0F)) << 1]); + } + + /* Backdrop color modified during HBLANK (Road Rash 1,2,3)*/ + if ((v_counter < bitmap.viewport.h) && (cycles <= (mcycles_vdp + 860))) + { + /* remap entire line */ + remap_line(v_counter); + } + } + break; + } + + case 8: /* Horizontal Scroll (Mode 4 only) */ + { + int line; + + /* Hscroll is latched at HCount 0xF3, HCount 0xF6 on MD */ + /* Line starts at HCount 0xF4, HCount 0xF6 on MD */ + if (system_hw < SYSTEM_MD) + { + cycles = cycles + 15; + } + + /* Make sure Hscroll has not already been latched */ + line = (lines_per_frame + (cycles / MCYCLES_PER_LINE) - 1) % lines_per_frame; + if ((line > v_counter) && (line < bitmap.viewport.h) && !(work_ram[0x1ffb] & cart.special)) + { + v_counter = line; + render_line(line); + } + + reg[8] = d; + break; + } + + case 11: /* CTRL #3 */ + { + reg[11] = d; + + /* Horizontal scrolling mode */ + hscroll_mask = hscroll_mask_table[d & 0x03]; + + /* Vertical Scrolling mode */ + if (d & 0x04) + { + render_bg = im2_flag ? render_bg_m5_im2_vs : render_bg_m5_vs; + } + else + { + render_bg = im2_flag ? render_bg_m5_im2 : render_bg_m5; + } + break; + } + + case 12: /* CTRL #4 */ + { + /* Look for changed bits */ + r = d ^ reg[12]; + reg[12] = d; + + /* Shadow & Highlight mode */ + if (r & 0x08) + { + /* Reset color palette */ + int i; + color_update_m5(0x00, *(uint16 *)&cram[border << 1]); + for (i = 1; i < 0x40; i++) + { + color_update_m5(i, *(uint16 *)&cram[i << 1]); + } + + /* Update sprite rendering function */ + if (d & 0x08) + { + render_obj = im2_flag ? render_obj_m5_im2_ste : render_obj_m5_ste; + } + else + { + render_obj = im2_flag ? render_obj_m5_im2 : render_obj_m5; + } + } + + /* Interlaced modes */ + if (r & 0x06) + { + /* changes should be applied on next frame */ + bitmap.viewport.changed |= 2; + } + + /* Active display width */ + if (r & 0x01) + { + if (d & 0x01) + { + /* Update display-dependant registers */ + ntwb = (reg[3] << 10) & 0xF000; + satb = (reg[5] << 9) & 0xFC00; + sat_base_mask = 0xFC00; + sat_addr_mask = 0x03FF; + + /* Update HC table */ + hctab = cycle2hc40; + + /* Update clipping */ + window_clip(reg[17], 1); + + /* Max. sprite pixels per line */ + max_sprite_pixels = 320; + } + else + { + /* Update display-dependant registers */ + ntwb = (reg[3] << 10) & 0xF800; + satb = (reg[5] << 9) & 0xFE00; + sat_base_mask = 0xFE00; + sat_addr_mask = 0x01FF; + + /* Update HC table */ + hctab = cycle2hc32; + + /* Update clipping */ + window_clip(reg[17], 0); + + /* Max. sprite pixels per line */ + max_sprite_pixels = 256; + } + + /* Active display width modified during HBLANK (Bugs Bunny Double Trouble) */ + if ((v_counter < bitmap.viewport.h) && (cycles <= (mcycles_vdp + 860))) + { + /* Update active display width */ + bitmap.viewport.w = 256 + ((d & 1) << 6); + + /* Redraw entire line */ + render_line(v_counter); + } + else if (v_counter == (lines_per_frame - 1)) + { + /* Update starting frame active display width */ + bitmap.viewport.w = 256 + ((d & 1) << 6); + } + else + { + /* Changes should be applied on next frame (Golden Axe III intro) */ + /* NB: not 100% accurate but required since backend framebuffer width cannot be modified mid-frame. */ + /* This would require a fixed framebuffer width (based on TV screen aspect ratio) and pixel scaling */ + /* to be done during rendering (depending on active display pixel aspect ratio in H32 or H40 mode). */ + /* Display is generally disabled when this is modified so it shouldn't be really noticeable anyway. */ + bitmap.viewport.changed |= 2; + } + } + break; + } + + case 13: /* HScroll Base Address */ + { + reg[13] = d; + hscb = (d << 10) & 0xFC00; + break; + } + + case 16: /* Playfield size */ + { + reg[16] = d; + playfield_shift = shift_table[(d & 3)]; + playfield_col_mask = col_mask_table[(d & 3)]; + playfield_row_mask = row_mask_table[(d >> 4) & 3]; + break; + } + + case 17: /* Window/Plane A vertical clipping */ + { + reg[17] = d; + window_clip(d, reg[12] & 1); + break; + } + + default: + { + reg[r] = d; + break; + } + } +} + +/*--------------------------------------------------------------------------*/ +/* FIFO emulation (Mega Drive VDP specific) */ +/* ---------------------------------------- */ +/* */ +/* CPU access to VRAM, CRAM & VSRAM is limited during active display: */ +/* H32 mode -> 16 access per line */ +/* H40 mode -> 18 access per line */ +/* */ +/* with fixed access slots timings detailled below. */ +/* */ +/* Each VRAM access is byte wide, so one VRAM write (word) need two slots. */ +/* */ +/*--------------------------------------------------------------------------*/ + +static void vdp_fifo_update(unsigned int cycles) +{ + int slots, count = 0; + + const int *fifo_timing; + + const int fifo_cycles_h32[16+2] = + { + 230, 510, 810, 970, 1130, 1450, 1610, 1770, 2090, 2250, 2410, 2730, 2890, 3050, 3350, 3370, + MCYCLES_PER_LINE + 230, MCYCLES_PER_LINE + 510 + }; + + const int fifo_cycles_h40[18+2] = + { + 352, 820, 948, 1076, 1332, 1460, 1588, 1844, 1972, 2100, 2356, 2484, 2612, 2868, 2996, 3124, 3364, 3380, + MCYCLES_PER_LINE + 352, MCYCLES_PER_LINE + 820 + }; + + + /* number of access slots up to current line */ + if (reg[12] & 0x01) + { + fifo_timing = fifo_cycles_h40; + slots = 18 * (cycles / MCYCLES_PER_LINE); + } + else + { + fifo_timing = fifo_cycles_h32; + slots = 16 * (cycles / MCYCLES_PER_LINE); + } + + /* number of access slots within current line */ + cycles = cycles % MCYCLES_PER_LINE; + while (fifo_timing[count] <= cycles) + { + count++; + } + + /* number of processed FIFO entries since last access */ + slots = (slots + count - fifo_slots) >> fifo_byte_access; + + if (slots > 0) + { + /* process FIFO entries */ + fifo_write_cnt -= slots; + + /* Clear FIFO full flag */ + status &= 0xFEFF; + + if (fifo_write_cnt <= 0) + { + /* No more FIFO entries */ + fifo_write_cnt = 0; + + /* Set FIFO empty flag */ + status |= 0x200; + } + + /* Update FIFO access slot counter */ + fifo_slots += (slots << fifo_byte_access); + } + + /* next FIFO update cycle */ + fifo_cycles = mcycles_vdp + fifo_timing[count | fifo_byte_access]; +} + + +/*--------------------------------------------------------------------------*/ +/* Internal 16-bit data bus access function (Mode 5 only) */ +/*--------------------------------------------------------------------------*/ +static void vdp_bus_w(unsigned int data) +{ + /* write data to next FIFO entry */ + fifo[fifo_idx] = data; + + /* increment FIFO write pointer */ + fifo_idx = (fifo_idx + 1) & 3; + + /* Check destination code (CD0-CD3) */ + switch (code & 0x0F) + { + case 0x01: /* VRAM */ + { + /* VRAM address */ + int index = addr & 0xFFFE; + + /* Pointer to VRAM */ + uint16 *p = (uint16 *)&vram[index]; + + /* Byte-swap data if A0 is set */ + if (addr & 1) + { + data = ((data >> 8) | (data << 8)) & 0xFFFF; + } + + /* Intercept writes to Sprite Attribute Table */ + if ((index & sat_base_mask) == satb) + { + /* Update internal SAT */ + *(uint16 *) &sat[index & sat_addr_mask] = data; + } + + /* Only write unique data to VRAM */ + if (data != *p) + { + int name; + + /* Write data to VRAM */ + *p = data; + + /* Update pattern cache */ + MARK_BG_DIRTY (index); + } + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, m68k.cycles/MCYCLES_PER_LINE-1, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif + break; + } + + case 0x03: /* CRAM */ + { + /* Pointer to CRAM 9-bit word */ + uint16 *p = (uint16 *)&cram[addr & 0x7E]; + + /* Pack 16-bit bus data (BBB0GGG0RRR0) to 9-bit CRAM data (BBBGGGRRR) */ + data = ((data & 0xE00) >> 3) | ((data & 0x0E0) >> 2) | ((data & 0x00E) >> 1); + + /* Check if CRAM data is being modified */ + if (data != *p) + { + /* CRAM index (64 words) */ + int index = (addr >> 1) & 0x3F; + + /* Write CRAM data */ + *p = data; + + /* Color entry 0 of each palette is never displayed (transparent pixel) */ + if (index & 0x0F) + { + /* Update color palette */ + color_update_m5(index, data); + } + + /* Update backdrop color */ + if (index == border) + { + color_update_m5(0x00, data); + } + + /* CRAM modified during HBLANK (Striker, Zero the Kamikaze, etc) */ + if ((v_counter < bitmap.viewport.h) && (reg[1]& 0x40) && (m68k.cycles <= (mcycles_vdp + 860))) + { + /* Remap current line */ + remap_line(v_counter); + } + } +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] CRAM 0x%x write -> 0x%x (%x)\n", v_counter, m68k.cycles/MCYCLES_PER_LINE-1, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif + break; + } + + case 0x05: /* VSRAM */ + { + *(uint16 *)&vsram[addr & 0x7E] = data; + + /* 2-cell Vscroll mode */ + if (reg[11] & 0x04) + { + /* VSRAM writes during HBLANK (Adventures of Batman & Robin) */ + if ((v_counter < bitmap.viewport.h) && (reg[1] & 0x40) && (m68k.cycles <= (mcycles_vdp + 860))) + { + /* Remap current line */ + render_line(v_counter); + } + } +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VSRAM 0x%x write -> 0x%x (%x)\n", v_counter, m68k.cycles/MCYCLES_PER_LINE-1, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif + break; + } + + default: + { + /* add some delay until 68k periodical wait-states are accurately emulated ("Clue", "Microcosm") */ + m68k.cycles += 2; +#ifdef LOGERROR + error("[%d(%d)][%d(%d)] Invalid (%d) 0x%x write -> 0x%x (%x)\n", v_counter, m68k.cycles/MCYCLES_PER_LINE-1, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, code, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif + break; + } + } + + /* Increment address register */ + addr += reg[15]; +} + + +/*--------------------------------------------------------------------------*/ +/* 68k bus interface (Mega Drive VDP only) */ +/*--------------------------------------------------------------------------*/ + +static void vdp_68k_data_w_m4(unsigned int data) +{ + /* Clear pending flag */ + pending = 0; + + /* Restricted VDP writes during active display */ + if (!(status & 8) && (reg[1] & 0x40)) + { + /* Update VDP FIFO */ + vdp_fifo_update(m68k.cycles); + + /* Clear FIFO empty flag */ + status &= 0xFDFF; + + /* up to 4 words can be stored */ + if (fifo_write_cnt < 4) + { + /* Increment FIFO counter */ + fifo_write_cnt++; + + /* Set FIFO full flag if 4 words are stored */ + status |= ((fifo_write_cnt & 4) << 6); + } + else + { + /* CPU is halted until next FIFO entry processing */ + m68k.cycles = fifo_cycles; + + /* Update FIFO access slot counter */ + fifo_slots = fifo_slots + 1 + fifo_byte_access; + } + } + + /* Check destination code */ + if (code & 0x02) + { + /* CRAM index (32 words) */ + int index = addr & 0x1F; + + /* Pointer to CRAM 9-bit word */ + uint16 *p = (uint16 *)&cram[index << 1]; + + /* Pack 16-bit data (xxx000BBGGRR) to 9-bit CRAM data (xxxBBGGRR) */ + data = ((data & 0xE00) >> 3) | (data & 0x3F); + + /* Check if CRAM data is being modified */ + if (data != *p) + { + /* Write CRAM data */ + *p = data; + + /* Update color palette */ + color_update_m4(index, data); + + /* Update backdrop color */ + if (index == (0x10 | (border & 0x0F))) + { + color_update_m4(0x40, data); + } + } + } + else + { + /* VRAM address (interleaved format) */ + int index = ((addr << 1) & 0x3FC) | ((addr & 0x200) >> 8) | (addr & 0x3C00); + + /* Pointer to VRAM */ + uint16 *p = (uint16 *)&vram[index]; + + /* Byte-swap data if A0 is set */ + if (addr & 1) + { + data = ((data >> 8) | (data << 8)) & 0xFFFF; + } + + /* Only write unique data to VRAM */ + if (data != *p) + { + int name; + + /* Write data to VRAM */ + *p = data; + + /* Update the pattern cache */ + MARK_BG_DIRTY (index); + } + } + + /* Increment address register (TODO: check how address is incremented in Mode 4) */ + addr += (reg[15] + 1); +} + +static void vdp_68k_data_w_m5(unsigned int data) +{ + /* Clear pending flag */ + pending = 0; + + /* Restricted VDP writes during active display */ + if (!(status & 8) && (reg[1] & 0x40)) + { + /* Update VDP FIFO */ + vdp_fifo_update(m68k.cycles); + + /* Clear FIFO empty flag */ + status &= 0xFDFF; + + /* up to 4 words can be stored */ + if (fifo_write_cnt < 4) + { + /* Increment FIFO counter */ + fifo_write_cnt++; + + /* Set FIFO full flag if 4 words are stored */ + status |= ((fifo_write_cnt & 4) << 6); + } + else + { + /* CPU is halted until next FIFO entry processing (Chaos Engine / Soldiers of Fortune, Double Clutch, Titan Overdrive Demo) */ + m68k.cycles = fifo_cycles; + + /* Update FIFO access slot counter */ + fifo_slots += (1 + fifo_byte_access); + } + } + + /* Write data */ + vdp_bus_w(data); + + /* Check if DMA Fill is pending */ + if (dmafill) + { + /* Clear DMA Fill pending flag */ + dmafill = 0; + + /* DMA length */ + dma_length = (reg[20] << 8) | reg[19]; + + /* Zero DMA length (pre-decrementing counter) */ + if (!dma_length) + { + dma_length = 0x10000; + } + + /* Trigger DMA */ + vdp_dma_update(m68k.cycles); + } +} + +static unsigned int vdp_68k_data_r_m4(void) +{ + /* VRAM address (interleaved format) */ + int index = ((addr << 1) & 0x3FC) | ((addr & 0x200) >> 8) | (addr & 0x3C00); + + /* Clear pending flag */ + pending = 0; + + /* Increment address register (TODO: check how address is incremented in Mode 4) */ + addr += (reg[15] + 1); + + /* Read VRAM data */ + return *(uint16 *) &vram[index]; +} + +static unsigned int vdp_68k_data_r_m5(void) +{ + uint16 data = 0; + + /* Clear pending flag */ + pending = 0; + + /* Check destination code (CD0-CD3) & CD4 */ + switch (code & 0x1F) + { + case 0x00: + { + /* read two bytes from VRAM */ + data = *(uint16 *)&vram[addr & 0xFFFE]; + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VRAM 0x%x read -> 0x%x (%x)\n", v_counter, m68k.cycles/MCYCLES_PER_LINE-1, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif + break; + } + + case 0x04: + { + /* VSRAM index */ + int index = addr & 0x7E; + + /* Check against VSRAM max size (80 x 11-bits) */ + if (index >= 0x50) + { + /* Wrap to address 0 (TODO: check if still true with Genesis 3 model) */ + index = 0; + } + + /* Read 11-bit word from VSRAM */ + data = *(uint16 *)&vsram[index] & 0x7FF; + + /* Unused bits are set using data from next available FIFO entry */ + data |= (fifo[fifo_idx] & ~0x7FF); + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VSRAM 0x%x read -> 0x%x (%x)\n", v_counter, m68k.cycles/MCYCLES_PER_LINE-1, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif + break; + } + + case 0x08: + { + /* Read 9-bit word from CRAM */ + data = *(uint16 *)&cram[addr & 0x7E]; + + /* Unpack 9-bit CRAM data (BBBGGGRRR) to 16-bit bus data (BBB0GGG0RRR0) */ + data = ((data & 0x1C0) << 3) | ((data & 0x038) << 2) | ((data & 0x007) << 1); + + /* Unused bits are set using data from next available FIFO entry */ + data |= (fifo[fifo_idx] & ~0xEEE); + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] CRAM 0x%x read -> 0x%x (%x)\n", v_counter, m68k.cycles/MCYCLES_PER_LINE-1, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif + break; + } + + case 0x0c: /* undocumented 8-bit VRAM read */ + { + /* Read one byte from VRAM adjacent address */ + data = READ_BYTE(vram, addr ^ 1); + + /* Unused bits are set using data from next available FIFO entry */ + data |= (fifo[fifo_idx] & ~0xFF); + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] 8-bit VRAM 0x%x read -> 0x%x (%x)\n", v_counter, m68k.cycles/MCYCLES_PER_LINE-1, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC)); +#endif + break; + } + + default: + { + /* Invalid code value (normally locks VDP, hard reset required) */ +#ifdef LOGERROR + error("[%d(%d)][%d(%d)] Invalid (%d) 0x%x read (%x)\n", v_counter, m68k.cycles/MCYCLES_PER_LINE-1, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, code, addr, m68k_get_reg(M68K_REG_PC)); +#endif + break; + } + } + + /* Increment address register */ + addr += reg[15]; + + /* Return data */ + return data; +} + + +/*--------------------------------------------------------------------------*/ +/* Z80 bus interface (Mega Drive VDP in Master System compatibility mode) */ +/*--------------------------------------------------------------------------*/ + +static void vdp_z80_data_w_m4(unsigned int data) +{ + /* Clear pending flag */ + pending = 0; + + /* Check destination code */ + if (code & 0x02) + { + /* CRAM index (32 words) */ + int index = addr & 0x1F; + + /* Pointer to CRAM word */ + uint16 *p = (uint16 *)&cram[index << 1]; + + /* Check if CRAM data is being modified */ + if (data != *p) + { + /* Write CRAM data */ + *p = data; + + /* Update color palette */ + color_update_m4(index, data); + + /* Update backdrop color */ + if (index == (0x10 | (border & 0x0F))) + { + color_update_m4(0x40, data); + } + } + } + else + { + /* VRAM address */ + int index = addr & 0x3FFF; + + /* Only write unique data to VRAM */ + if (data != vram[index]) + { + int name; + + /* Write data */ + vram[index] = data; + + /* Update pattern cache */ + MARK_BG_DIRTY(index); + } + } + + /* Increment address register (TODO: check how address is incremented in Mode 4) */ + addr += (reg[15] + 1); +} + +static void vdp_z80_data_w_m5(unsigned int data) +{ + /* Clear pending flag */ + pending = 0; + + /* Push byte into FIFO */ + fifo[fifo_idx] = data << 8; + fifo_idx = (fifo_idx + 1) & 3; + + /* Check destination code (CD0-CD3) */ + switch (code & 0x0F) + { + case 0x01: /* VRAM */ + { + /* VRAM address (write low byte to even address & high byte to odd address) */ + int index = addr ^ 1; + + /* Intercept writes to Sprite Attribute Table */ + if ((index & sat_base_mask) == satb) + { + /* Update internal SAT */ + WRITE_BYTE(sat, index & sat_addr_mask, data); + } + + /* Only write unique data to VRAM */ + if (data != READ_BYTE(vram, index)) + { + int name; + + /* Write data */ + WRITE_BYTE(vram, index, data); + + /* Update pattern cache */ + MARK_BG_DIRTY (index); + } + break; + } + + case 0x03: /* CRAM */ + { + /* Pointer to CRAM word */ + uint16 *p = (uint16 *)&cram[addr & 0x7E]; + + /* Pack 8-bit value into 9-bit CRAM data */ + if (addr & 1) + { + /* Write high byte (0000BBB0 -> BBBxxxxxx) */ + data = (*p & 0x3F) | ((data & 0x0E) << 5); + } + else + { + /* Write low byte (GGG0RRR0 -> xxxGGGRRR) */ + data = (*p & 0x1C0) | ((data & 0x0E) >> 1)| ((data & 0xE0) >> 2); + } + + /* Check if CRAM data is being modified */ + if (data != *p) + { + /* CRAM index (64 words) */ + int index = (addr >> 1) & 0x3F; + + /* Write CRAM data */ + *p = data; + + /* Color entry 0 of each palette is never displayed (transparent pixel) */ + if (index & 0x0F) + { + /* Update color palette */ + color_update_m5(index, data); + } + + /* Update backdrop color */ + if (index == border) + { + color_update_m5(0x00, data); + } + } + break; + } + + case 0x05: /* VSRAM */ + { + /* Write low byte to even address & high byte to odd address */ + WRITE_BYTE(vsram, (addr & 0x7F) ^ 1, data); + break; + } + } + + /* Increment address register */ + addr += reg[15]; + + /* Check if DMA Fill is pending */ + if (dmafill) + { + /* Clear DMA Fill pending flag */ + dmafill = 0; + + /* DMA length */ + dma_length = (reg[20] << 8) | reg[19]; + + /* Zero DMA length (pre-decrementing counter) */ + if (!dma_length) + { + dma_length = 0x10000; + } + + /* Trigger DMA */ + vdp_dma_update(Z80.cycles); + } +} + +static unsigned int vdp_z80_data_r_m4(void) +{ + /* Read buffer */ + unsigned int data = fifo[0]; + + /* Clear pending flag */ + pending = 0; + + /* Process next read */ + fifo[0] = vram[addr & 0x3FFF]; + + /* Increment address register (TODO: check how address is incremented in Mode 4) */ + addr += (reg[15] + 1); + + /* Return data */ + return data; +} + +static unsigned int vdp_z80_data_r_m5(void) +{ + unsigned int data = 0; + + /* Clear pending flag */ + pending = 0; + + /* Check destination code (CD0-CD3) & CD4 */ + switch (code & 0x1F) + { + case 0x00: /* VRAM */ + { + /* Return low byte from even address & high byte from odd address */ + data = READ_BYTE(vram, addr ^ 1); + break; + } + + case 0x04: /* VSRAM */ + { + /* Return low byte from even address & high byte from odd address */ + data = READ_BYTE(vsram, (addr & 0x7F) ^ 1); + break; + } + + case 0x08: /* CRAM */ + { + /* Read CRAM data */ + data = *(uint16 *)&cram[addr & 0x7E]; + + /* Unpack 9-bit CRAM data (BBBGGGRRR) to 16-bit data (BBB0GGG0RRR0) */ + data = ((data & 0x1C0) << 3) | ((data & 0x038) << 2) | ((data & 0x007) << 1); + + /* Return low byte from even address & high byte from odd address */ + if (addr & 1) + { + data = data >> 8; + } + + data &= 0xFF; + break; + } + } + + /* Increment address register */ + addr += reg[15]; + + /* Return data */ + return data; +} + + +/*-----------------------------------------------------------------------------*/ +/* Z80 bus interface (Master System, Game Gear & SG-1000 VDP) */ +/*-----------------------------------------------------------------------------*/ + +static void vdp_z80_data_w_ms(unsigned int data) +{ + /* Clear pending flag */ + pending = 0; + + if (code < 3) + { + int index; + + /* Check if we are already on next line */ + int line = (lines_per_frame + (Z80.cycles / MCYCLES_PER_LINE) - 1) % lines_per_frame; + if ((line > v_counter) && (line < bitmap.viewport.h) && !(work_ram[0x1ffb] & cart.special)) + { + /* Render next line */ + v_counter = line; + render_line(line); + } + + /* VRAM address */ + index = addr & 0x3FFF; + + /* VRAM write */ + if (data != vram[index]) + { + int name; + vram[index] = data; + MARK_BG_DIRTY(index); + } + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, Z80.cycles/MCYCLES_PER_LINE-1, Z80.cycles, Z80.cycles%MCYCLES_PER_LINE, index, data, Z80.pc.w.l); +#endif + } + else + { + /* CRAM address */ + int index = addr & 0x1F; + + /* Pointer to CRAM word */ + uint16 *p = (uint16 *)&cram[index << 1]; + + /* Check if CRAM data is being modified */ + if (data != *p) + { + /* Write CRAM data */ + *p = data; + + /* Update color palette */ + color_update_m4(index, data); + + /* Update backdrop color */ + if (index == (0x10 | (border & 0x0F))) + { + color_update_m4(0x40, data); + } + } +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] CRAM 0x%x write -> 0x%x (%x)\n", v_counter, Z80.cycles/MCYCLES_PER_LINE-1, Z80.cycles, Z80.cycles%MCYCLES_PER_LINE, addr, data, Z80.pc.w.l); +#endif + } + + /* Update read buffer */ + fifo[0] = data; + + /* Update address register */ + addr++; +} + +static void vdp_z80_data_w_gg(unsigned int data) +{ + /* Clear pending flag */ + pending = 0; + + if (code < 3) + { + int index; + + /* Check if we are already on next line*/ + int line = (lines_per_frame + (Z80.cycles / MCYCLES_PER_LINE) - 1) % lines_per_frame; + if ((line > v_counter) && (line < bitmap.viewport.h) && !(work_ram[0x1ffb] & cart.special)) + { + /* Render next line */ + v_counter = line; + render_line(line); + } + + /* VRAM address */ + index = addr & 0x3FFF; + + /* VRAM write */ + if (data != vram[index]) + { + int name; + vram[index] = data; + MARK_BG_DIRTY(index); + } +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, Z80.cycles/MCYCLES_PER_LINE-1, Z80.cycles, Z80.cycles%MCYCLES_PER_LINE, index, data, Z80.pc.w.l); +#endif + } + else + { + if (addr & 1) + { + /* Pointer to CRAM word */ + uint16 *p = (uint16 *)&cram[addr & 0x3E]; + + /* 12-bit data word */ + data = (data << 8) | cached_write; + + /* Check if CRAM data is being modified */ + if (data != *p) + { + /* Color index (0-31) */ + int index = (addr >> 1) & 0x1F; + + /* Write CRAM data */ + *p = data; + + /* Update color palette */ + color_update_m4(index, data); + + /* Update backdrop color */ + if (index == (0x10 | (border & 0x0F))) + { + color_update_m4(0x40, data); + } + } + } + else + { + /* Latch LSB */ + cached_write = data; + } +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] CRAM 0x%x write -> 0x%x (%x)\n", v_counter, Z80.cycles/MCYCLES_PER_LINE-1, Z80.cycles, Z80.cycles%MCYCLES_PER_LINE, addr, data, Z80.pc.w.l); +#endif + } + + /* Update read buffer */ + fifo[0] = data; + + /* Update address register */ + addr++; +} + +static void vdp_z80_data_w_sg(unsigned int data) +{ + /* VRAM address */ + int index = addr & 0x3FFF; + + /* Clear pending flag */ + pending = 0; + + /* 4K address decoding (cf. tms9918a.txt) */ + if (!(reg[1] & 0x80)) + { + index = (index & 0x203F) | ((index >> 6) & 0x40) | ((index << 1) & 0x1F80); + } + + /* VRAM write */ + vram[index] = data; + + /* Update address register */ + addr++; + +#ifdef LOGVDP + error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, Z80.cycles/MCYCLES_PER_LINE-1, Z80.cycles, Z80.cycles%MCYCLES_PER_LINE, index, data, Z80.pc.w.l); +#endif +} + +/*--------------------------------------------------------------------------*/ +/* DMA operations (Mega Drive VDP only) */ +/*--------------------------------------------------------------------------*/ + +/* DMA from 68K bus: $000000-$7FFFFF (external area) */ +static void vdp_dma_68k_ext(unsigned int length) +{ + uint16 data; + + /* 68k bus source address */ + uint32 source = (reg[23] << 17) | (dma_src << 1); + + do + { + /* Read data word from 68k bus */ + if (m68k.memory_map[source>>16].read16) + { + data = m68k.memory_map[source>>16].read16(source); + } + else + { + data = *(uint16 *)(m68k.memory_map[source>>16].base + (source & 0xFFFF)); + } + + /* Increment source address */ + source += 2; + + /* 128k DMA window */ + source = (reg[23] << 17) | (source & 0x1FFFF); + + /* Write data word to VRAM, CRAM or VSRAM */ + vdp_bus_w(data); + } + while (--length); + + /* Update DMA source address */ + dma_src = (source >> 1) & 0xffff; +} + +/* DMA from 68K bus: $800000-$FFFFFF (internal area) except I/O area */ +static void vdp_dma_68k_ram(unsigned int length) +{ + uint16 data; + + /* 68k bus source address */ + uint32 source = (reg[23] << 17) | (dma_src << 1); + + do + { + /* access Work-RAM by default */ + data = *(uint16 *)(work_ram + (source & 0xFFFF)); + + /* Increment source address */ + source += 2; + + /* 128k DMA window */ + source = (reg[23] << 17) | (source & 0x1FFFF); + + /* Write data word to VRAM, CRAM or VSRAM */ + vdp_bus_w(data); + } + while (--length); + + /* Update DMA source address */ + dma_src = (source >> 1) & 0xffff; +} + +/* DMA from 68K bus: $A00000-$A1FFFF (I/O area) specific */ +static void vdp_dma_68k_io(unsigned int length) +{ + uint16 data; + + /* 68k bus source address */ + uint32 source = (reg[23] << 17) | (dma_src << 1); + + do + { + /* Z80 area */ + if (source <= 0xA0FFFF) + { + /* Return $FFFF only when the Z80 isn't hogging the Z-bus. + (e.g. Z80 isn't reset and 68000 has the bus) */ + data = ((zstate ^ 3) ? *(uint16 *)(work_ram + (source & 0xFFFF)) : 0xFFFF); + } + + /* The I/O chip and work RAM try to drive the data bus which results + in both values being combined in random ways when read. + We return the I/O chip values which seem to have precedence, */ + else if (source <= 0xA1001F) + { + data = io_68k_read((source >> 1) & 0x0F); + data = (data << 8 | data); + } + + /* All remaining locations access work RAM */ + else + { + data = *(uint16 *)(work_ram + (source & 0xFFFF)); + } + + /* Increment source address */ + source += 2; + + /* 128k DMA window */ + source = (reg[23] << 17) | (source & 0x1FFFF); + + /* Write data to VRAM, CRAM or VSRAM */ + vdp_bus_w(data); + } + while (--length); + + /* Update DMA source address */ + dma_src = (source >> 1) & 0xffff; +} + +/* VRAM Copy */ +static void vdp_dma_copy(unsigned int length) +{ + /* CD4 should be set (CD0-CD3 ignored) otherwise VDP locks (hard reset needed) */ + if (code & 0x10) + { + int name; + uint8 data; + + /* VRAM source address */ + uint16 source = dma_src; + + do + { + /* Read byte from adjacent VRAM source address */ + data = READ_BYTE(vram, source ^ 1); + + /* Intercept writes to Sprite Attribute Table */ + if ((addr & sat_base_mask) == satb) + { + /* Update internal SAT */ + WRITE_BYTE(sat, (addr & sat_addr_mask) ^ 1, data); + } + + /* Write byte to adjacent VRAM destination address */ + WRITE_BYTE(vram, addr ^ 1, data); + + /* Update pattern cache */ + MARK_BG_DIRTY(addr); + + /* Increment VRAM source address */ + source++; + + /* Increment VRAM destination address */ + addr += reg[15]; + } + while (--length); + + /* Update DMA source address */ + dma_src = source; + } +} + +/* DMA Fill */ +static void vdp_dma_fill(unsigned int length) +{ + /* Check destination code (CD0-CD3) */ + switch (code & 0x0F) + { + case 0x01: /* VRAM */ + { + int name; + + /* Get source data from last written FIFO entry */ + uint8 data = fifo[(fifo_idx+3)&3] >> 8; + + do + { + /* Intercept writes to Sprite Attribute Table */ + if ((addr & sat_base_mask) == satb) + { + /* Update internal SAT */ + WRITE_BYTE(sat, (addr & sat_addr_mask) ^ 1, data); + } + + /* Write byte to adjacent VRAM address */ + WRITE_BYTE(vram, addr ^ 1, data); + + /* Update pattern cache */ + MARK_BG_DIRTY (addr); + + /* Increment VRAM address */ + addr += reg[15]; + } + while (--length); + break; + } + + case 0x03: /* CRAM */ + { + /* Get source data from next available FIFO entry */ + uint16 data = fifo[fifo_idx]; + + /* Pack 16-bit bus data (BBB0GGG0RRR0) to 9-bit CRAM data (BBBGGGRRR) */ + data = ((data & 0xE00) >> 3) | ((data & 0x0E0) >> 2) | ((data & 0x00E) >> 1); + + do + { + /* Pointer to CRAM 9-bit word */ + uint16 *p = (uint16 *)&cram[addr & 0x7E]; + + /* Check if CRAM data is being modified */ + if (data != *p) + { + /* CRAM index (64 words) */ + int index = (addr >> 1) & 0x3F; + + /* Write CRAM data */ + *p = data; + + /* Color entry 0 of each palette is never displayed (transparent pixel) */ + if (index & 0x0F) + { + /* Update color palette */ + color_update_m5(index, data); + } + + /* Update backdrop color */ + if (index == border) + { + color_update_m5(0x00, data); + } + } + + /* Increment CRAM address */ + addr += reg[15]; + } + while (--length); + break; + } + + case 0x05: /* VSRAM */ + { + /* Get source data from next available FIFO entry */ + uint16 data = fifo[fifo_idx]; + + do + { + /* Write VSRAM data */ + *(uint16 *)&vsram[addr & 0x7E] = data; + + /* Increment VSRAM address */ + addr += reg[15]; + } + while (--length); + break; + } + + default: + { + /* invalid destination does nothing (Williams Greatest Hits after soft reset) */ + + /* address is still incremented */ + addr += reg[15] * length; + } + } +} diff --git a/genplus-gx/core/vdp_ctrl.h b/genplus-gx/core/vdp_ctrl.h new file mode 100644 index 0000000000..8a8ee8d7df --- /dev/null +++ b/genplus-gx/core/vdp_ctrl.h @@ -0,0 +1,105 @@ +/*************************************************************************************** + * Genesis Plus + * Video Display Processor (68k & Z80 CPU interface) + * + * Support for SG-1000, Master System (315-5124 & 315-5246), Game Gear & Mega Drive VDP + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _VDP_H_ +#define _VDP_H_ + +/* VDP context */ +extern uint8 reg[0x20]; +extern uint8 sat[0x400]; +extern uint8 vram[0x10000]; +extern uint8 cram[0x80]; +extern uint8 vsram[0x80]; +extern uint8 hint_pending; +extern uint8 vint_pending; +extern uint16 status; +extern uint32 dma_length; + +/* Global variables */ +extern uint16 ntab; +extern uint16 ntbb; +extern uint16 ntwb; +extern uint16 satb; +extern uint16 hscb; +extern uint8 bg_name_dirty[0x800]; +extern uint16 bg_name_list[0x800]; +extern uint16 bg_list_index; +extern uint8 hscroll_mask; +extern uint8 playfield_shift; +extern uint8 playfield_col_mask; +extern uint16 playfield_row_mask; +extern uint8 odd_frame; +extern uint8 im2_flag; +extern uint8 interlaced; +extern uint8 vdp_pal; +extern uint16 v_counter; +extern uint16 vc_max; +extern uint16 vscroll; +extern uint16 lines_per_frame; +extern uint16 max_sprite_pixels; +extern int32 fifo_write_cnt; +extern uint32 fifo_slots; +extern uint32 hvc_latch; +extern const uint8 *hctab; + +/* Function pointers */ +extern void (*vdp_68k_data_w)(unsigned int data); +extern void (*vdp_z80_data_w)(unsigned int data); +extern unsigned int (*vdp_68k_data_r)(void); +extern unsigned int (*vdp_z80_data_r)(void); + +/* Function prototypes */ +extern void vdp_init(void); +extern void vdp_reset(void); +extern int vdp_context_save(uint8 *state); +extern int vdp_context_load(uint8 *state, uint8 version); +extern void vdp_dma_update(unsigned int cycles); +extern void vdp_68k_ctrl_w(unsigned int data); +extern void vdp_z80_ctrl_w(unsigned int data); +extern void vdp_sms_ctrl_w(unsigned int data); +extern void vdp_tms_ctrl_w(unsigned int data); +extern unsigned int vdp_68k_ctrl_r(unsigned int cycles); +extern unsigned int vdp_z80_ctrl_r(unsigned int cycles); +extern unsigned int vdp_hvc_r(unsigned int cycles); +extern void vdp_test_w(unsigned int data); +extern int vdp_68k_irq_ack(int int_level); + +#endif /* _VDP_H_ */ diff --git a/genplus-gx/core/vdp_render.c b/genplus-gx/core/vdp_render.c new file mode 100644 index 0000000000..9496e51ab0 --- /dev/null +++ b/genplus-gx/core/vdp_render.c @@ -0,0 +1,4206 @@ +/*************************************************************************************** + * Genesis Plus + * Video Display Processor (Modes 0, 1, 2, 3, 4 & 5 rendering) + * + * Support for SG-1000, Master System (315-5124 & 315-5246), Game Gear & Mega Drive VDP + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "md_ntsc.h" +#include "sms_ntsc.h" + +/*** NTSC Filters ***/ +extern md_ntsc_t *md_ntsc; +extern sms_ntsc_t *sms_ntsc; + + +/* Output pixels type*/ +#if defined(USE_8BPP_RENDERING) +#define PIXEL_OUT_T uint8 +#elif defined(USE_32BPP_RENDERING) +#define PIXEL_OUT_T uint32 +#else +#define PIXEL_OUT_T uint16 +#endif + + +/* Pixel priority look-up tables information */ +#define LUT_MAX (6) +#define LUT_SIZE (0x10000) + + +#ifdef ALIGN_LONG +#undef READ_LONG +#undef WRITE_LONG + +INLINE uint32 READ_LONG(void *address) +{ + if ((uint32)address & 3) + { +#ifdef LSB_FIRST /* little endian version */ + return ( *((uint8 *)address) + + (*((uint8 *)address+1) << 8) + + (*((uint8 *)address+2) << 16) + + (*((uint8 *)address+3) << 24) ); +#else /* big endian version */ + return ( *((uint8 *)address+3) + + (*((uint8 *)address+2) << 8) + + (*((uint8 *)address+1) << 16) + + (*((uint8 *)address) << 24) ); +#endif /* LSB_FIRST */ + } + else return *(uint32 *)address; +} + +INLINE void WRITE_LONG(void *address, uint32 data) +{ + if ((uint32)address & 3) + { +#ifdef LSB_FIRST + *((uint8 *)address) = data; + *((uint8 *)address+1) = (data >> 8); + *((uint8 *)address+2) = (data >> 16); + *((uint8 *)address+3) = (data >> 24); +#else + *((uint8 *)address+3) = data; + *((uint8 *)address+2) = (data >> 8); + *((uint8 *)address+1) = (data >> 16); + *((uint8 *)address) = (data >> 24); +#endif /* LSB_FIRST */ + return; + } + else *(uint32 *)address = data; +} + +#endif /* ALIGN_LONG */ + + +/* Draw 2-cell column (8-pixels high) */ +/* + Pattern cache base address: VHN NNNNNNNN NNYYYxxx + with : + x = Pattern Pixel (0-7) + Y = Pattern Row (0-7) + N = Pattern Number (0-2047) from pattern attribute + H = Horizontal Flip bit from pattern attribute + V = Vertical Flip bit from pattern attribute +*/ +#define GET_LSB_TILE(ATTR, LINE) \ + atex = atex_table[(ATTR >> 13) & 7]; \ + src = (uint32 *)&bg_pattern_cache[(ATTR & 0x00001FFF) << 6 | (LINE)]; +#define GET_MSB_TILE(ATTR, LINE) \ + atex = atex_table[(ATTR >> 29) & 7]; \ + src = (uint32 *)&bg_pattern_cache[(ATTR & 0x1FFF0000) >> 10 | (LINE)]; + +/* Draw 2-cell column (16 pixels high) */ +/* + Pattern cache base address: VHN NNNNNNNN NYYYYxxx + with : + x = Pattern Pixel (0-7) + Y = Pattern Row (0-15) + N = Pattern Number (0-1023) + H = Horizontal Flip bit + V = Vertical Flip bit +*/ +#define GET_LSB_TILE_IM2(ATTR, LINE) \ + atex = atex_table[(ATTR >> 13) & 7]; \ + src = (uint32 *)&bg_pattern_cache[((ATTR & 0x000003FF) << 7 | (ATTR & 0x00001800) << 6 | (LINE)) ^ ((ATTR & 0x00001000) >> 6)]; +#define GET_MSB_TILE_IM2(ATTR, LINE) \ + atex = atex_table[(ATTR >> 29) & 7]; \ + src = (uint32 *)&bg_pattern_cache[((ATTR & 0x03FF0000) >> 9 | (ATTR & 0x18000000) >> 10 | (LINE)) ^ ((ATTR & 0x10000000) >> 22)]; + +/* + One column = 2 tiles + Two pattern attributes are written in VRAM as two consecutives 16-bit words: + + P = priority bit + C = color palette (2 bits) + V = Vertical Flip bit + H = Horizontal Flip bit + N = Pattern Number (11 bits) + + (MSB) PCCVHNNN NNNNNNNN (LSB) (MSB) PCCVHNNN NNNNNNNN (LSB) + PATTERN1 PATTERN2 + + Both pattern attributes are read from VRAM as one 32-bit word: + + LIT_ENDIAN: (MSB) PCCVHNNN NNNNNNNN PCCVHNNN NNNNNNNN (LSB) + PATTERN2 PATTERN1 + + BIG_ENDIAN: (MSB) PCCVHNNN NNNNNNNN PCCVHNNN NNNNNNNN (LSB) + PATTERN1 PATTERN2 + + + In line buffers, one pixel = one byte: (msb) 0Pppcccc (lsb) + with: + P = priority bit (from pattern attribute) + p = color palette (from pattern attribute) + c = color data (from pattern cache) + + One pattern = 8 pixels = 8 bytes = two 32-bit writes per pattern +*/ + +#ifdef ALIGN_LONG +#ifdef LSB_FIRST +#define DRAW_COLUMN(ATTR, LINE) \ + GET_LSB_TILE(ATTR, LINE) \ + WRITE_LONG(dst, src[0] | atex); \ + dst++; \ + WRITE_LONG(dst, src[1] | atex); \ + dst++; \ + GET_MSB_TILE(ATTR, LINE) \ + WRITE_LONG(dst, src[0] | atex); \ + dst++; \ + WRITE_LONG(dst, src[1] | atex); \ + dst++; +#define DRAW_COLUMN_IM2(ATTR, LINE) \ + GET_LSB_TILE_IM2(ATTR, LINE) \ + WRITE_LONG(dst, src[0] | atex); \ + dst++; \ + WRITE_LONG(dst, src[1] | atex); \ + dst++; \ + GET_MSB_TILE_IM2(ATTR, LINE) \ + WRITE_LONG(dst, src[0] | atex); \ + dst++; \ + WRITE_LONG(dst, src[1] | atex); \ + dst++; +#else +#define DRAW_COLUMN(ATTR, LINE) \ + GET_MSB_TILE(ATTR, LINE) \ + WRITE_LONG(dst, src[0] | atex); \ + dst++; \ + WRITE_LONG(dst, src[1] | atex); \ + dst++; \ + GET_LSB_TILE(ATTR, LINE) \ + WRITE_LONG(dst, src[0] | atex); \ + dst++; \ + WRITE_LONG(dst, src[1] | atex); \ + dst++; +#define DRAW_COLUMN_IM2(ATTR, LINE) \ + GET_MSB_TILE_IM2(ATTR, LINE) \ + WRITE_LONG(dst, src[0] | atex); \ + dst++; \ + WRITE_LONG(dst, src[1] | atex); \ + dst++; \ + GET_LSB_TILE_IM2(ATTR, LINE) \ + WRITE_LONG(dst, src[0] | atex); \ + dst++; \ + WRITE_LONG(dst, src[1] | atex); \ + dst++; +#endif +#else /* NOT ALIGNED */ +#ifdef LSB_FIRST +#define DRAW_COLUMN(ATTR, LINE) \ + GET_LSB_TILE(ATTR, LINE) \ + *dst++ = (src[0] | atex); \ + *dst++ = (src[1] | atex); \ + GET_MSB_TILE(ATTR, LINE) \ + *dst++ = (src[0] | atex); \ + *dst++ = (src[1] | atex); +#define DRAW_COLUMN_IM2(ATTR, LINE) \ + GET_LSB_TILE_IM2(ATTR, LINE) \ + *dst++ = (src[0] | atex); \ + *dst++ = (src[1] | atex); \ + GET_MSB_TILE_IM2(ATTR, LINE) \ + *dst++ = (src[0] | atex); \ + *dst++ = (src[1] | atex); +#else +#define DRAW_COLUMN(ATTR, LINE) \ + GET_MSB_TILE(ATTR, LINE) \ + *dst++ = (src[0] | atex); \ + *dst++ = (src[1] | atex); \ + GET_LSB_TILE(ATTR, LINE) \ + *dst++ = (src[0] | atex); \ + *dst++ = (src[1] | atex); +#define DRAW_COLUMN_IM2(ATTR, LINE) \ + GET_MSB_TILE_IM2(ATTR, LINE) \ + *dst++ = (src[0] | atex); \ + *dst++ = (src[1] | atex); \ + GET_LSB_TILE_IM2(ATTR, LINE) \ + *dst++ = (src[0] | atex); \ + *dst++ = (src[1] | atex); +#endif +#endif /* ALIGN_LONG */ + +#ifdef ALT_RENDERER +/* Draw background tiles directly using priority look-up table */ +/* SRC_A = layer A rendered pixel line (4 bytes = 4 pixels at once) */ +/* SRC_B = layer B cached pixel line (4 bytes = 4 pixels at once) */ +/* Note: cache address is always aligned so no need to use READ_LONG macro */ +/* This might be faster or slower than original method, depending on */ +/* architecture (x86, PowerPC), cache size, memory access speed, etc... */ + +#ifdef LSB_FIRST +#define DRAW_BG_TILE(SRC_A, SRC_B) \ + *lb++ = table[((SRC_B << 8) & 0xff00) | (SRC_A & 0xff)]; \ + *lb++ = table[(SRC_B & 0xff00) | ((SRC_A >> 8) & 0xff)]; \ + *lb++ = table[((SRC_B >> 8) & 0xff00) | ((SRC_A >> 16) & 0xff)]; \ + *lb++ = table[((SRC_B >> 16) & 0xff00) | ((SRC_A >> 24) & 0xff)]; +#else +#define DRAW_BG_TILE(SRC_A, SRC_B) \ + *lb++ = table[((SRC_B >> 16) & 0xff00) | ((SRC_A >> 24) & 0xff)]; \ + *lb++ = table[((SRC_B >> 8) & 0xff00) | ((SRC_A >> 16) & 0xff)]; \ + *lb++ = table[(SRC_B & 0xff00) | ((SRC_A >> 8) & 0xff)]; \ + *lb++ = table[((SRC_B << 8) & 0xff00) | (SRC_A & 0xff)]; +#endif + +#ifdef ALIGN_LONG +#ifdef LSB_FIRST +#define DRAW_BG_COLUMN(ATTR, LINE, SRC_A, SRC_B) \ + GET_LSB_TILE(ATTR, LINE) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + GET_MSB_TILE(ATTR, LINE) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) +#define DRAW_BG_COLUMN_IM2(ATTR, LINE, SRC_A, SRC_B) \ + GET_LSB_TILE_IM2(ATTR, LINE) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + GET_MSB_TILE_IM2(ATTR, LINE) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) +#else +#define DRAW_BG_COLUMN(ATTR, LINE, SRC_A, SRC_B) \ + GET_MSB_TILE(ATTR, LINE) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + GET_LSB_TILE(ATTR, LINE) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) +#define DRAW_BG_COLUMN_IM2(ATTR, LINE, SRC_A, SRC_B) \ + GET_MSB_TILE_IM2(ATTR, LINE) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + GET_LSB_TILE_IM2(ATTR, LINE) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = READ_LONG((uint32 *)lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) +#endif +#else /* NOT ALIGNED */ +#ifdef LSB_FIRST +#define DRAW_BG_COLUMN(ATTR, LINE, SRC_A, SRC_B) \ + GET_LSB_TILE(ATTR, LINE) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + GET_MSB_TILE(ATTR, LINE) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) +#define DRAW_BG_COLUMN_IM2(ATTR, LINE, SRC_A, SRC_B) \ + GET_LSB_TILE_IM2(ATTR, LINE) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + GET_MSB_TILE_IM2(ATTR, LINE) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) +#else +#define DRAW_BG_COLUMN(ATTR, LINE, SRC_A, SRC_B) \ + GET_MSB_TILE(ATTR, LINE) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + GET_LSB_TILE(ATTR, LINE) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) +#define DRAW_BG_COLUMN_IM2(ATTR, LINE, SRC_A, SRC_B) \ + GET_MSB_TILE_IM2(ATTR, LINE) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + GET_LSB_TILE_IM2(ATTR, LINE) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[0] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) \ + SRC_A = *(uint32 *)(lb); \ + SRC_B = (src[1] | atex); \ + DRAW_BG_TILE(SRC_A, SRC_B) +#endif +#endif /* ALIGN_LONG */ +#endif /* ALT_RENDERER */ + +#define DRAW_SPRITE_TILE(WIDTH,ATTR,TABLE) \ + for (i=0;i> 10); \ + } \ + } + +#define DRAW_SPRITE_TILE_ACCURATE(WIDTH,ATTR,TABLE) \ + for (i=0;i> 1); \ + status |= 0x20; \ + } \ + } \ + } + +#define DRAW_SPRITE_TILE_ACCURATE_2X(WIDTH,ATTR,TABLE) \ + for (i=0;i> 1); \ + status |= 0x20; \ + } \ + temp &= 0x00FF; \ + temp |= (lb[i+1] << 8); \ + lb[i+1] = TABLE[temp | ATTR]; \ + if ((temp & 0x8000) && !(status & 0x20)) \ + { \ + spr_col = (v_counter << 8) | ((xpos + i + 1 + 13) >> 1); \ + status |= 0x20; \ + } \ + } \ + } + + +/* Pixels conversion macro */ +/* 4-bit color channels are either compressed to 2/3-bit or dithered to 5/6/8-bit equivalents */ +/* 3:3:2 RGB */ +#if defined(USE_8BPP_RENDERING) +#define MAKE_PIXEL(r,g,b) (((r) >> 1) << 5 | ((g) >> 1) << 2 | (b) >> 2) + +/* 5:5:5 RGB */ +#elif defined(USE_15BPP_RENDERING) +#define MAKE_PIXEL(r,g,b) ((r) << 11 | ((r) >> 3) << 10 | (g) << 6 | ((g) >> 3) << 5 | (b) << 1 | (b) >> 3) + +/* 5:6:5 RGB */ +#elif defined(USE_16BPP_RENDERING) +#define MAKE_PIXEL(r,g,b) ((r) << 12 | ((r) >> 3) << 11 | (g) << 7 | ((g) >> 2) << 5 | (b) << 1 | (b) >> 3) + +/* 8:8:8 RGB */ +#elif defined(USE_32BPP_RENDERING) +#define MAKE_PIXEL(r,g,b) ((r) << 20 | (r) << 16 | (g) << 12 | (g) << 8 | (b) << 4 | (b)) +#endif + +/* Window & Plane A clipping */ +static struct clip_t +{ + uint8 left; + uint8 right; + uint8 enable; +} clip[2]; + +/* Pattern attribute (priority + palette bits) expansion table */ +static const uint32 atex_table[] = +{ + 0x00000000, + 0x10101010, + 0x20202020, + 0x30303030, + 0x40404040, + 0x50505050, + 0x60606060, + 0x70707070 +}; + +/* fixed Master System palette for Modes 0,1,2,3 */ +static const uint8 tms_crom[16] = +{ + 0x00, 0x00, 0x08, 0x0C, + 0x10, 0x30, 0x01, 0x3C, + 0x02, 0x03, 0x05, 0x0F, + 0x04, 0x33, 0x15, 0x3F +}; + +/* original SG-1000 palette */ +#if defined(USE_8BPP_RENDERING) +static const uint8 tms_palette[16] = +{ + 0x00, 0x00, 0x39, 0x79, + 0x4B, 0x6F, 0xC9, 0x5B, + 0xE9, 0xED, 0xD5, 0xD9, + 0x35, 0xCE, 0xDA, 0xFF +}; + +#elif defined(USE_15BPP_RENDERING) +static const uint16 tms_palette[16] = +{ + 0x0000, 0x0000, 0x1308, 0x2F6F, + 0x295D, 0x3DDF, 0x6949, 0x23BE, + 0x7D4A, 0x7DEF, 0x6B0A, 0x7330, + 0x12A7, 0x6177, 0x6739, 0x7FFF +}; + +#elif defined(USE_16BPP_RENDERING) +static const uint16 tms_palette[16] = +{ + 0x0000, 0x0000, 0x2648, 0x5ECF, + 0x52BD, 0x7BBE, 0xD289, 0x475E, + 0xF2AA, 0xFBCF, 0xD60A, 0xE670, + 0x2567, 0xC2F7, 0xCE59, 0xFFFF +}; + +#elif defined(USE_32BPP_RENDERING) +static const uint32 tms_palette[16] = +{ + 0x000000, 0x000000, 0x21C842, 0x5EDC78, + 0x5455ED, 0x7D76FC, 0xD4524D, 0x42EBF5, + 0xFC5554, 0xFF7978, 0xD4C154, 0xE6CE80, + 0x21B03B, 0xC95BB4, 0xCCCCCC, 0xFFFFFF +}; +#endif + +/* Cached and flipped patterns */ +static uint8 bg_pattern_cache[0x80000]; + +/* Sprite pattern name offset look-up table (Mode 5) */ +static uint8 name_lut[0x400]; + +/* Bitplane to packed pixel look-up table (Mode 4) */ +static uint32 bp_lut[0x10000]; + +/* Layer priority pixel look-up tables */ +static uint8 lut[LUT_MAX][LUT_SIZE]; + +/* Output pixel data look-up tables*/ +static PIXEL_OUT_T pixel[0x100]; +static PIXEL_OUT_T pixel_lut[3][0x200]; +static PIXEL_OUT_T pixel_lut_m4[0x40]; + +/* Background & Sprite line buffers */ +static uint8 linebuf[2][0x200]; + +/* Sprite limit flag */ +static uint8 spr_ovr; + +/* Sprite parsing lists */ +typedef struct +{ + uint16 ypos; + uint16 xpos; + uint16 attr; + uint16 size; +} object_info_t; + +static object_info_t obj_info[2][20]; + +/* Sprite Counter */ +static uint8 object_count[2]; + +/* Sprite Collision Info */ +uint16 spr_col; + +/* Function pointers */ +void (*render_bg)(int line); +void (*render_obj)(int line); +void (*parse_satb)(int line); +void (*update_bg_pattern_cache)(int index); + + +/*--------------------------------------------------------------------------*/ +/* Sprite pattern name offset look-up table function (Mode 5) */ +/*--------------------------------------------------------------------------*/ + +static void make_name_lut(void) +{ + int vcol, vrow; + int width, height; + int flipx, flipy; + int i; + + for (i = 0; i < 0x400; i += 1) + { + /* Sprite settings */ + vcol = i & 3; + vrow = (i >> 2) & 3; + height = (i >> 4) & 3; + width = (i >> 6) & 3; + flipx = (i >> 8) & 1; + flipy = (i >> 9) & 1; + + if ((vrow > height) || vcol > width) + { + /* Invalid settings (unused) */ + name_lut[i] = -1; + } + else + { + /* Adjust column & row index if sprite is flipped */ + if(flipx) vcol = (width - vcol); + if(flipy) vrow = (height - vrow); + + /* Pattern offset (pattern order is up->down->left->right) */ + name_lut[i] = vrow + (vcol * (height + 1)); + } + } +} + + +/*--------------------------------------------------------------------------*/ +/* Bitplane to packed pixel look-up table function (Mode 4) */ +/*--------------------------------------------------------------------------*/ + +static void make_bp_lut(void) +{ + int x,i,j; + uint32 out; + + /* ---------------------- */ + /* Pattern color encoding */ + /* -------------------------------------------------------------------------*/ + /* 4 byteplanes are required to define one pattern line (8 pixels) */ + /* A single pixel color is coded with 4 bits (c3 c2 c1 c0) */ + /* Each bit is coming from byteplane bits, as explained below: */ + /* pixel 0: c3 = bp3 bit 7, c2 = bp2 bit 7, c1 = bp1 bit 7, c0 = bp0 bit 7 */ + /* pixel 1: c3 = bp3 bit 6, c2 = bp2 bit 6, c1 = bp1 bit 6, c0 = bp0 bit 6 */ + /* ... */ + /* pixel 7: c3 = bp3 bit 0, c2 = bp2 bit 0, c1 = bp1 bit 0, c0 = bp0 bit 0 */ + /* -------------------------------------------------------------------------*/ + + for(i = 0; i < 0x100; i++) + for(j = 0; j < 0x100; j++) + { + out = 0; + for(x = 0; x < 8; x++) + { + /* pixel line data = hh00gg00ff00ee00dd00cc00bb00aa00 (32-bit) */ + /* aa-hh = upper or lower 2-bit values of pixels 0-7 (shifted) */ + out |= (j & (0x80 >> x)) ? (uint32)(8 << (x << 2)) : 0; + out |= (i & (0x80 >> x)) ? (uint32)(4 << (x << 2)) : 0; + } + + /* i = low byte in VRAM (bp0 or bp2) */ + /* j = high byte in VRAM (bp1 or bp3) */ + #ifdef LSB_FIRST + bp_lut[(j << 8) | (i)] = out; + #else + bp_lut[(i << 8) | (j)] = out; + #endif + } +} + + +/*--------------------------------------------------------------------------*/ +/* Layers priority pixel look-up tables functions */ +/*--------------------------------------------------------------------------*/ + +/* Input (bx): d5-d0=color, d6=priority, d7=unused */ +/* Input (ax): d5-d0=color, d6=priority, d7=unused */ +/* Output: d5-d0=color, d6=priority, d7=zero */ +static uint32 make_lut_bg(uint32 bx, uint32 ax) +{ + int bf = (bx & 0x7F); + int bp = (bx & 0x40); + int b = (bx & 0x0F); + + int af = (ax & 0x7F); + int ap = (ax & 0x40); + int a = (ax & 0x0F); + + int c = (ap ? (a ? af : bf) : (bp ? (b ? bf : af) : (a ? af : bf))); + + /* Strip palette & priority bits from transparent pixels */ + if((c & 0x0F) == 0x00) c &= 0x80; + + return (c); +} + +/* Input (bx): d5-d0=color, d6=priority, d7=unused */ +/* Input (sx): d5-d0=color, d6=priority, d7=unused */ +/* Output: d5-d0=color, d6=priority, d7=intensity select (0=half/1=normal) */ +static uint32 make_lut_bg_ste(uint32 bx, uint32 ax) +{ + int bf = (bx & 0x7F); + int bp = (bx & 0x40); + int b = (bx & 0x0F); + + int af = (ax & 0x7F); + int ap = (ax & 0x40); + int a = (ax & 0x0F); + + int c = (ap ? (a ? af : bf) : (bp ? (b ? bf : af) : (a ? af : bf))); + + /* Half intensity when both pixels are low priority */ + c |= ((ap | bp) << 1); + + /* Strip palette & priority bits from transparent pixels */ + if((c & 0x0F) == 0x00) c &= 0x80; + + return (c); +} + +/* Input (bx): d5-d0=color, d6=priority/1, d7=sprite pixel marker */ +/* Input (sx): d5-d0=color, d6=priority, d7=unused */ +/* Output: d5-d0=color, d6=priority, d7=sprite pixel marker */ +static uint32 make_lut_obj(uint32 bx, uint32 sx) +{ + int c; + + int bf = (bx & 0x7F); + int bs = (bx & 0x80); + int sf = (sx & 0x7F); + + if((sx & 0x0F) == 0) return bx; + + c = (bs ? bf : sf); + + /* Strip palette bits from transparent pixels */ + if((c & 0x0F) == 0x00) c &= 0xC0; + + return (c | 0x80); +} + + +/* Input (bx): d5-d0=color, d6=priority, d7=opaque sprite pixel marker */ +/* Input (sx): d5-d0=color, d6=priority, d7=unused */ +/* Output: d5-d0=color, d6=zero/priority, d7=opaque sprite pixel marker */ +static uint32 make_lut_bgobj(uint32 bx, uint32 sx) +{ + int c; + + int bf = (bx & 0x3F); + int bs = (bx & 0x80); + int bp = (bx & 0x40); + int b = (bx & 0x0F); + + int sf = (sx & 0x3F); + int sp = (sx & 0x40); + int s = (sx & 0x0F); + + if(s == 0) return bx; + + /* Previous sprite has higher priority */ + if(bs) return bx; + + c = (sp ? sf : (bp ? (b ? bf : sf) : sf)); + + /* Strip palette & priority bits from transparent pixels */ + if((c & 0x0F) == 0x00) c &= 0x80; + + return (c | 0x80); +} + +/* Input (bx): d5-d0=color, d6=priority, d7=intensity (half/normal) */ +/* Input (sx): d5-d0=color, d6=priority, d7=sprite marker */ +/* Output: d5-d0=color, d6=intensity (half/normal), d7=(double/invalid) */ +static uint32 make_lut_bgobj_ste(uint32 bx, uint32 sx) +{ + int c; + + int bf = (bx & 0x3F); + int bp = (bx & 0x40); + int b = (bx & 0x0F); + int bi = (bx & 0x80) >> 1; + + int sf = (sx & 0x3F); + int sp = (sx & 0x40); + int s = (sx & 0x0F); + int si = sp | bi; + + if(sp) + { + if(s) + { + if((sf & 0x3E) == 0x3E) + { + if(sf & 1) + { + c = (bf | 0x00); + } + else + { + c = (bx & 0x80) ? (bf | 0x80) : (bf | 0x40); + } + } + else + { + if(sf == 0x0E || sf == 0x1E || sf == 0x2E) + { + c = (sf | 0x40); + } + else + { + c = (sf | si); + } + } + } + else + { + c = (bf | bi); + } + } + else + { + if(bp) + { + if(b) + { + c = (bf | bi); + } + else + { + if(s) + { + if((sf & 0x3E) == 0x3E) + { + if(sf & 1) + { + c = (bf | 0x00); + } + else + { + c = (bx & 0x80) ? (bf | 0x80) : (bf | 0x40); + } + } + else + { + if(sf == 0x0E || sf == 0x1E || sf == 0x2E) + { + c = (sf | 0x40); + } + else + { + c = (sf | si); + } + } + } + else + { + c = (bf | bi); + } + } + } + else + { + if(s) + { + if((sf & 0x3E) == 0x3E) + { + if(sf & 1) + { + c = (bf | 0x00); + } + else + { + c = (bx & 0x80) ? (bf | 0x80) : (bf | 0x40); + } + } + else + { + if(sf == 0x0E || sf == 0x1E || sf == 0x2E) + { + c = (sf | 0x40); + } + else + { + c = (sf | si); + } + } + } + else + { + c = (bf | bi); + } + } + } + + if((c & 0x0f) == 0x00) c &= 0xC0; + + return (c); +} + +/* Input (bx): d3-d0=color, d4=palette, d5=priority, d6=zero, d7=sprite pixel marker */ +/* Input (sx): d3-d0=color, d7-d4=zero */ +/* Output: d3-d0=color, d4=palette, d5=zero/priority, d6=zero, d7=sprite pixel marker */ +static uint32 make_lut_bgobj_m4(uint32 bx, uint32 sx) +{ + int c; + + int bf = (bx & 0x3F); + int bs = (bx & 0x80); + int bp = (bx & 0x20); + int b = (bx & 0x0F); + + int s = (sx & 0x0F); + int sf = (s | 0x10); /* force palette bit */ + + /* Transparent sprite pixel */ + if(s == 0) return bx; + + /* Previous sprite has higher priority */ + if(bs) return bx; + + /* note: priority bit is always 0 for Modes 0,1,2,3 */ + c = (bp ? (b ? bf : sf) : sf); + + return (c | 0x80); +} + + +/*--------------------------------------------------------------------------*/ +/* Pixel layer merging function */ +/*--------------------------------------------------------------------------*/ + +INLINE void merge(uint8 *srca, uint8 *srcb, uint8 *dst, uint8 *table, int width) +{ + do + { + *dst++ = table[(*srcb++ << 8) | (*srca++)]; + } + while (--width); +} + + +/*--------------------------------------------------------------------------*/ +/* Pixel color lookup tables initialization */ +/*--------------------------------------------------------------------------*/ + +static void palette_init(void) +{ + int r, g, b, i; + + /************************************************/ + /* Each R,G,B color channel is 4-bit with a */ + /* total of 15 different intensity levels. */ + /* */ + /* Color intensity depends on the mode: */ + /* */ + /* normal : xxx0 (0-14) */ + /* shadow : 0xxx (0-7) */ + /* highlight: 1xxx - 1 (7-14) */ + /* mode4 : xxxx(*) (0-15) */ + /* GG mode : xxxx (0-15) */ + /* */ + /* with x = original CRAM value (2, 3 or 4-bit) */ + /* (*) 2-bit CRAM value is expanded to 4-bit */ + /************************************************/ + + /* Initialize Mode 5 pixel color look-up tables */ + for (i = 0; i < 0x200; i++) + { + /* CRAM 9-bit value (BBBGGGRRR) */ + r = (i >> 0) & 7; + g = (i >> 3) & 7; + b = (i >> 6) & 7; + + /* Convert to output pixel format */ + pixel_lut[0][i] = MAKE_PIXEL(r,g,b); + pixel_lut[1][i] = MAKE_PIXEL(r<<1,g<<1,b<<1); + pixel_lut[2][i] = MAKE_PIXEL(r+7,g+7,b+7); + } + + /* Initialize Mode 4 pixel color look-up table */ + for (i = 0; i < 0x40; i++) + { + /* CRAM 6-bit value (000BBGGRR) */ + r = (i >> 0) & 3; + g = (i >> 2) & 3; + b = (i >> 4) & 3; + + /* Expand to full range & convert to output pixel format */ + pixel_lut_m4[i] = MAKE_PIXEL((r << 2) | r, (g << 2) | g, (b << 2) | b); + } +} + + +/*--------------------------------------------------------------------------*/ +/* Color palette update functions */ +/*--------------------------------------------------------------------------*/ + +void color_update_m4(int index, unsigned int data) +{ + switch (system_hw) + { + case SYSTEM_GG: + { + /* CRAM value (BBBBGGGGRRRR) */ + int r = (data >> 0) & 0x0F; + int g = (data >> 4) & 0x0F; + int b = (data >> 8) & 0x0F; + + /* Convert to output pixel */ + data = MAKE_PIXEL(r,g,b); + break; + } + + case SYSTEM_SG: + { + /* Fixed TMS99xx palette */ + if (index & 0x0F) + { + /* Colors 1-15 */ + data = tms_palette[index & 0x0F]; + } + else + { + /* Backdrop color */ + data = tms_palette[reg[7] & 0x0F]; + } + break; + } + + default: + { + /* Test M4 bit */ + if (!(reg[0] & 0x04)) + { + if (system_hw & SYSTEM_MD) + { + /* Invalid Mode (black screen) */ + data = 0x00; + } + else if (system_hw != SYSTEM_GGMS) + { + /* Fixed CRAM palette */ + if (index & 0x0F) + { + /* Colors 1-15 */ + data = tms_crom[index & 0x0F]; + } + else + { + /* Backdrop color */ + data = tms_crom[reg[7] & 0x0F]; + } + } + } + + /* Mode 4 palette */ + data = pixel_lut_m4[data & 0x3F]; + break; + } + } + + + /* Input pixel: x0xiiiii (normal) or 01000000 (backdrop) */ + if (reg[0] & 0x04) + { + /* Mode 4 */ + pixel[0x00 | index] = data; + pixel[0x20 | index] = data; + pixel[0x80 | index] = data; + pixel[0xA0 | index] = data; + } + else + { + /* TMS99xx modes (palette bit forced to 1 because Game Gear uses CRAM palette #1) */ + if ((index == 0x40) || (index == (0x10 | (reg[7] & 0x0F)))) + { + /* Update backdrop color */ + pixel[0x40] = data; + + /* Update transparent color */ + pixel[0x10] = data; + pixel[0x30] = data; + pixel[0x90] = data; + pixel[0xB0] = data; + } + + if (index & 0x0F) + { + /* update non-transparent colors */ + pixel[0x00 | index] = data; + pixel[0x20 | index] = data; + pixel[0x80 | index] = data; + pixel[0xA0 | index] = data; + } + } +} + +void color_update_m5(int index, unsigned int data) +{ + /* Palette Mode */ + if (!(reg[0] & 0x04)) + { + /* Color value is limited to 00X00X00X */ + data &= 0x49; + } + + if(reg[12] & 0x08) + { + /* Mode 5 (Shadow/Normal/Highlight) */ + pixel[0x00 | index] = pixel_lut[0][data]; + pixel[0x40 | index] = pixel_lut[1][data]; + pixel[0x80 | index] = pixel_lut[2][data]; + } + else + { + /* Mode 5 (Normal) */ + data = pixel_lut[1][data]; + + /* Input pixel: xxiiiiii */ + pixel[0x00 | index] = data; + pixel[0x40 | index] = data; + pixel[0x80 | index] = data; + } +} + + +/*--------------------------------------------------------------------------*/ +/* Background layers rendering functions */ +/*--------------------------------------------------------------------------*/ + +/* Graphics I */ +void render_bg_m0(int line) +{ + uint8 color, pattern; + uint16 name; + + uint8 *lb = &linebuf[0][0x20]; + uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line & 0xF8) << 2)]; + uint8 *ct = &vram[((reg[3] << 6) & 0x3FC0)]; + uint8 *pg = &vram[((reg[4] << 11) & 0x3800) + (line & 7)]; + + /* 32 x 8 pixels */ + int width = 32; + + do + { + name = *nt++; + color = ct[name >> 3]; + pattern = pg[name << 3]; + + *lb++ = 0x10 | ((color >> (((pattern >> 7) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 6) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 5) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 4) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 3) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 2) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 1) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 0) & 1) << 2)) & 0x0F); + } + while (--width); +} + +/* Text */ +void render_bg_m1(int line) +{ + uint8 pattern; + uint8 color = reg[7]; + + uint8 *lb = &linebuf[0][0x20]; + uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line >> 3) * 40)]; + uint8 *pg = &vram[((reg[4] << 11) & 0x3800) + (line & 7)]; + + /* 40 x 6 pixels */ + int width = 40; + + /* Left border (8 pixels) */ + memset (lb, 0x40, 8); + lb += 8; + + do + { + pattern = pg[*nt++]; + + *lb++ = 0x10 | ((color >> (((pattern >> 7) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 6) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 5) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 4) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 3) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 2) & 1) << 2)) & 0x0F); + } + while (--width); + + /* Right borders (8 pixels) */ + memset(lb, 0x40, 8); +} + +/* Text + extended PG */ +void render_bg_m1x(int line) +{ + uint8 pattern; + uint8 *pg; + + uint8 color = reg[7]; + + uint8 *lb = &linebuf[0][0x20]; + uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line >> 3) * 40)]; + + uint16 pg_mask = ~0x3800 ^ (reg[4] << 11); + + /* 40 x 6 pixels */ + int width = 40; + + /* Unused bits used as a mask on TMS99xx & 315-5124 VDP only */ + if (system_hw > SYSTEM_SMS) + { + pg_mask |= 0x1800; + } + + pg = &vram[((0x2000 + ((line & 0xC0) << 5)) & pg_mask) + (line & 7)]; + + /* Left border (8 pixels) */ + memset (lb, 0x40, 8); + lb += 8; + + do + { + pattern = pg[*nt++ << 3]; + + *lb++ = 0x10 | ((color >> (((pattern >> 7) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 6) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 5) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 4) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 3) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 2) & 1) << 2)) & 0x0F); + } + while (--width); + + /* Right borders (8 pixels) */ + memset(lb, 0x40, 8); +} + +/* Graphics II */ +void render_bg_m2(int line) +{ + uint8 color, pattern; + uint16 name; + uint8 *ct, *pg; + + uint8 *lb = &linebuf[0][0x20]; + uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line & 0xF8) << 2)]; + + uint16 ct_mask = ~0x3FC0 ^ (reg[3] << 6); + uint16 pg_mask = ~0x3800 ^ (reg[4] << 11); + + /* 32 x 8 pixels */ + int width = 32; + + /* Unused bits used as a mask on TMS99xx & 315-5124 VDP only */ + if (system_hw > SYSTEM_SMS) + { + ct_mask |= 0x1FC0; + pg_mask |= 0x1800; + } + + ct = &vram[((0x2000 + ((line & 0xC0) << 5)) & ct_mask) + (line & 7)]; + pg = &vram[((0x2000 + ((line & 0xC0) << 5)) & pg_mask) + (line & 7)]; + + do + { + name = *nt++ << 3 ; + color = ct[name & ct_mask]; + pattern = pg[name]; + + *lb++ = 0x10 | ((color >> (((pattern >> 7) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 6) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 5) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 4) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 3) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 2) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 1) & 1) << 2)) & 0x0F); + *lb++ = 0x10 | ((color >> (((pattern >> 0) & 1) << 2)) & 0x0F); + } + while (--width); +} + +/* Multicolor */ +void render_bg_m3(int line) +{ + uint8 color; + uint16 name; + + uint8 *lb = &linebuf[0][0x20]; + uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line & 0xF8) << 2)]; + uint8 *pg = &vram[((reg[4] << 11) & 0x3800) + ((line >> 2) & 7)]; + + /* 32 x 8 pixels */ + int width = 32; + + do + { + name = *nt++; + color = pg[name << 3]; + + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 0) & 0x0F); + *lb++ = 0x10 | ((color >> 0) & 0x0F); + *lb++ = 0x10 | ((color >> 0) & 0x0F); + *lb++ = 0x10 | ((color >> 0) & 0x0F); + } + while (--width); +} + +/* Multicolor + extended PG */ +void render_bg_m3x(int line) +{ + uint8 color; + uint16 name; + uint8 *pg; + + uint8 *lb = &linebuf[0][0x20]; + uint8 *nt = &vram[((reg[2] << 10) & 0x3C00) + ((line & 0xF8) << 2)]; + + uint16 pg_mask = ~0x3800 ^ (reg[4] << 11); + + /* 32 x 8 pixels */ + int width = 32; + + /* Unused bits used as a mask on TMS99xx & 315-5124 VDP only */ + if (system_hw > SYSTEM_SMS) + { + pg_mask |= 0x1800; + } + + pg = &vram[((0x2000 + ((line & 0xC0) << 5)) & pg_mask) + ((line >> 2) & 7)]; + + do + { + name = *nt++; + color = pg[name << 3]; + + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 0) & 0x0F); + *lb++ = 0x10 | ((color >> 0) & 0x0F); + *lb++ = 0x10 | ((color >> 0) & 0x0F); + *lb++ = 0x10 | ((color >> 0) & 0x0F); + } + while (--width); +} + +/* Invalid (2+3/1+2+3) */ +void render_bg_inv(int line) +{ + uint8 color = reg[7]; + + uint8 *lb = &linebuf[0][0x20]; + + /* 40 x 6 pixels */ + int width = 40; + + /* Left border (8 pixels) */ + memset (lb, 0x40, 8); + lb += 8; + + do + { + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 4) & 0x0F); + *lb++ = 0x10 | ((color >> 0) & 0x0F); + *lb++ = 0x10 | ((color >> 0) & 0x0F); + } + while (--width); + + /* Right borders (8 pixels) */ + memset(lb, 0x40, 8); +} + +/* Mode 4 */ +void render_bg_m4(int line) +{ + int column; + uint16 *nt; + uint32 attr, atex, *src; + + /* 32 x 8 pixels */ + int width = 32; + + /* Horizontal scrolling */ + int index = ((reg[0] & 0x40) && (line < 0x10)) ? 0x100 : reg[0x08]; + int shift = index & 7; + + /* Background line buffer */ + uint32 *dst = (uint32 *)&linebuf[0][0x20 + shift]; + + /* Vertical scrolling */ + int v_line = line + vscroll; + + /* Pattern name table mask */ + uint16 nt_mask = ~0x3C00 ^ (reg[2] << 10); + + /* Unused bits used as a mask on TMS99xx & 315-5124 VDP only */ + if (system_hw > SYSTEM_SMS) + { + nt_mask |= 0x400; + } + + /* Test for extended modes (Master System II & Game gear VDP only) */ + if (bitmap.viewport.h > 192) + { + /* Vertical scroll mask */ + v_line = v_line % 256; + + /* Pattern name Table */ + nt = (uint16 *)&vram[(0x3700 & nt_mask) + ((v_line >> 3) << 6)]; + } + else + { + /* Vertical scroll mask */ + v_line = v_line % 224; + + /* Pattern name Table */ + nt = (uint16 *)&vram[(0x3800 + ((v_line >> 3) << 6)) & nt_mask]; + } + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + /* Tile column index */ + index = (0x100 - index) >> 3; + + /* Clip left-most column if required */ + if (shift) + { + memset(&linebuf[0][0x20], 0, shift); + index++; + } + + /* Draw tiles */ + for(column = 0; column < width; column++, index++) + { + /* Stop vertical scrolling for rightmost eight tiles */ + if((column == 24) && (reg[0] & 0x80)) + { + /* Clear Pattern name table start address */ + if (bitmap.viewport.h > 192) + { + nt = (uint16 *)&vram[(0x3700 & nt_mask) + ((line >> 3) << 6)]; + } + else + { + nt = (uint16 *)&vram[(0x3800 + ((line >> 3) << 6)) & nt_mask]; + } + + /* Clear Pattern row index */ + v_line = (line & 7) << 3; + } + + /* Read name table attribute word */ + attr = nt[index % width]; +#ifndef LSB_FIRST + attr = (((attr & 0xFF) << 8) | ((attr & 0xFF00) >> 8)); +#endif + + /* Expand priority and palette bits */ + atex = atex_table[(attr >> 11) & 3]; + + /* Cached pattern data line (4 bytes = 4 pixels at once) */ + src = (uint32 *)&bg_pattern_cache[((attr & 0x7FF) << 6) | (v_line)]; + + /* Copy left & right half, adding the attribute bits in */ +#ifdef ALIGN_DWORD + WRITE_LONG(dst, src[0] | atex); + dst++; + WRITE_LONG(dst, src[1] | atex); + dst++; +#else + *dst++ = (src[0] | atex); + *dst++ = (src[1] | atex); +#endif + } +} + +/* Mode 5 */ +#ifndef ALT_RENDERER +void render_bg_m5(int line) +{ + int column; + uint32 atex, atbuf, *src, *dst; + + /* Common data */ + uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)]; + uint32 yscroll = *(uint32 *)&vsram[0]; + uint32 pf_col_mask = playfield_col_mask; + uint32 pf_row_mask = playfield_row_mask; + uint32 pf_shift = playfield_shift; + + /* Window & Plane A */ + int a = (reg[18] & 0x1F) << 3; + int w = (reg[18] >> 7) & 1; + + /* Plane B width */ + int start = 0; + int end = bitmap.viewport.w >> 4; + + /* Plane B scroll */ +#ifdef LSB_FIRST + uint32 shift = (xscroll >> 16) & 0x0F; + uint32 index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask); + uint32 v_line = (line + (yscroll >> 16)) & pf_row_mask; +#else + uint32 shift = (xscroll & 0x0F); + uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask); + uint32 v_line = (line + yscroll) & pf_row_mask; +#endif + + /* Plane B name table */ + uint32 *nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + if(shift) + { + /* Plane B line buffer */ + dst = (uint32 *)&linebuf[0][0x10 + shift]; + + atbuf = nt[(index - 1) & pf_col_mask]; + DRAW_COLUMN(atbuf, v_line) + } + else + { + /* Plane B line buffer */ + dst = (uint32 *)&linebuf[0][0x20]; + } + + for(column = 0; column < end; column++, index++) + { + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN(atbuf, v_line) + } + + if (w == (line >= a)) + { + /* Window takes up entire line */ + a = 0; + w = 1; + } + else + { + /* Window and Plane A share the line */ + a = clip[0].enable; + w = clip[1].enable; + } + + /* Plane A */ + if (a) + { + /* Plane A width */ + start = clip[0].left; + end = clip[0].right; + + /* Plane A scroll */ +#ifdef LSB_FIRST + shift = (xscroll & 0x0F); + index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask); + v_line = (line + yscroll) & pf_row_mask; +#else + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask); + v_line = (line + (yscroll >> 16)) & pf_row_mask; +#endif + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + if(shift) + { + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x10 + shift + (start << 4)]; + + /* Window bug */ + if (start) + { + atbuf = nt[index & pf_col_mask]; + } + else + { + atbuf = nt[(index - 1) & pf_col_mask]; + } + + DRAW_COLUMN(atbuf, v_line) + } + else + { + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x20 + (start << 4)]; + } + + for(column = start; column < end; column++, index++) + { + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN(atbuf, v_line) + } + + /* Window width */ + start = clip[1].left; + end = clip[1].right; + } + + /* Window */ + if (w) + { + /* Window name table */ + nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))]; + + /* Pattern row index */ + v_line = (line & 7) << 3; + + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x20 + (start << 4)]; + + for(column = start; column < end; column++) + { + atbuf = nt[column]; + DRAW_COLUMN(atbuf, v_line) + } + } + + /* Merge background layers */ + merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[(reg[12] & 0x08) >> 2], bitmap.viewport.w); +} + +void render_bg_m5_vs(int line) +{ + int column; + uint32 atex, atbuf, *src, *dst; + uint32 v_line, *nt; + + /* Common data */ + uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)]; + uint32 yscroll = 0; + uint32 pf_col_mask = playfield_col_mask; + uint32 pf_row_mask = playfield_row_mask; + uint32 pf_shift = playfield_shift; + uint32 *vs = (uint32 *)&vsram[0]; + + /* Window & Plane A */ + int a = (reg[18] & 0x1F) << 3; + int w = (reg[18] >> 7) & 1; + + /* Plane B width */ + int start = 0; + int end = bitmap.viewport.w >> 4; + + /* Plane B horizontal scroll */ +#ifdef LSB_FIRST + uint32 shift = (xscroll >> 16) & 0x0F; + uint32 index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask); +#else + uint32 shift = (xscroll & 0x0F); + uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask); +#endif + + /* Left-most column vertical scrolling when partially shown horizontally (verified on PAL MD2) */ + /* TODO: check on Genesis 3 models since it apparently behaves differently */ + /* In H32 mode, vertical scrolling is disabled, in H40 mode, same value is used for both planes */ + /* See Formula One / Kawasaki Superbike Challenge (H32) & Gynoug / Cutie Suzuki no Ringside Angel (H40) */ + if (reg[12] & 1) + { + yscroll = vs[19] & (vs[19] >> 16); + } + + if(shift) + { + /* Plane B vertical scroll */ + v_line = (line + yscroll) & pf_row_mask; + + /* Plane B name table */ + nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + /* Plane B line buffer */ + dst = (uint32 *)&linebuf[0][0x10 + shift]; + + atbuf = nt[(index - 1) & pf_col_mask]; + DRAW_COLUMN(atbuf, v_line) + } + else + { + /* Plane B line buffer */ + dst = (uint32 *)&linebuf[0][0x20]; + } + + for(column = 0; column < end; column++, index++) + { + /* Plane B vertical scroll */ +#ifdef LSB_FIRST + v_line = (line + (vs[column] >> 16)) & pf_row_mask; +#else + v_line = (line + vs[column]) & pf_row_mask; +#endif + + /* Plane B name table */ + nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN(atbuf, v_line) + } + + if (w == (line >= a)) + { + /* Window takes up entire line */ + a = 0; + w = 1; + } + else + { + /* Window and Plane A share the line */ + a = clip[0].enable; + w = clip[1].enable; + } + + /* Plane A */ + if (a) + { + /* Plane A width */ + start = clip[0].left; + end = clip[0].right; + + /* Plane A horizontal scroll */ +#ifdef LSB_FIRST + shift = (xscroll & 0x0F); + index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask); +#else + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask); +#endif + + if(shift) + { + /* Plane A vertical scroll */ + v_line = (line + yscroll) & pf_row_mask; + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x10 + shift + (start << 4)]; + + /* Window bug */ + if (start) + { + atbuf = nt[index & pf_col_mask]; + } + else + { + atbuf = nt[(index - 1) & pf_col_mask]; + } + + DRAW_COLUMN(atbuf, v_line) + } + else + { + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x20 + (start << 4)]; + } + + for(column = start; column < end; column++, index++) + { + /* Plane A vertical scroll */ +#ifdef LSB_FIRST + v_line = (line + vs[column]) & pf_row_mask; +#else + v_line = (line + (vs[column] >> 16)) & pf_row_mask; +#endif + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN(atbuf, v_line) + } + + /* Window width */ + start = clip[1].left; + end = clip[1].right; + } + + /* Window */ + if (w) + { + /* Window name table */ + nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))]; + + /* Pattern row index */ + v_line = (line & 7) << 3; + + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x20 + (start << 4)]; + + for(column = start; column < end; column++) + { + atbuf = nt[column]; + DRAW_COLUMN(atbuf, v_line) + } + } + + /* Merge background layers */ + merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[(reg[12] & 0x08) >> 2], bitmap.viewport.w); +} + +void render_bg_m5_im2(int line) +{ + int column; + uint32 atex, atbuf, *src, *dst; + + /* Common data */ + int odd = odd_frame; + uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)]; + uint32 yscroll = *(uint32 *)&vsram[0]; + uint32 pf_col_mask = playfield_col_mask; + uint32 pf_row_mask = playfield_row_mask; + uint32 pf_shift = playfield_shift; + + /* Window & Plane A */ + int a = (reg[18] & 0x1F) << 3; + int w = (reg[18] >> 7) & 1; + + /* Plane B width */ + int start = 0; + int end = bitmap.viewport.w >> 4; + + /* Plane B scroll */ +#ifdef LSB_FIRST + uint32 shift = (xscroll >> 16) & 0x0F; + uint32 index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask); + uint32 v_line = (line + (yscroll >> 17)) & pf_row_mask; +#else + uint32 shift = (xscroll & 0x0F); + uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask); + uint32 v_line = (line + (yscroll >> 1)) & pf_row_mask; +#endif + + /* Plane B name table */ + uint32 *nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + if(shift) + { + /* Plane B line buffer */ + dst = (uint32 *)&linebuf[0][0x10 + shift]; + + atbuf = nt[(index - 1) & pf_col_mask]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + else + { + /* Plane B line buffer */ + dst = (uint32 *)&linebuf[0][0x20]; + } + + for(column = 0; column < end; column++, index++) + { + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + + if (w == (line >= a)) + { + /* Window takes up entire line */ + a = 0; + w = 1; + } + else + { + /* Window and Plane A share the line */ + a = clip[0].enable; + w = clip[1].enable; + } + + /* Plane A */ + if (a) + { + /* Plane A width */ + start = clip[0].left; + end = clip[0].right; + + /* Plane A scroll */ +#ifdef LSB_FIRST + shift = (xscroll & 0x0F); + index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask); + v_line = (line + (yscroll >> 1)) & pf_row_mask; +#else + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask); + v_line = (line + (yscroll >> 17)) & pf_row_mask; +#endif + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + if(shift) + { + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x10 + shift + (start << 4)]; + + /* Window bug */ + if (start) + { + atbuf = nt[index & pf_col_mask]; + } + else + { + atbuf = nt[(index - 1) & pf_col_mask]; + } + + DRAW_COLUMN_IM2(atbuf, v_line) + } + else + { + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x20 + (start << 4)]; + } + + for(column = start; column < end; column++, index++) + { + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + + /* Window width */ + start = clip[1].left; + end = clip[1].right; + } + + /* Window */ + if (w) + { + /* Window name table */ + nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))]; + + /* Pattern row index */ + v_line = ((line & 7) << 1 | odd) << 3; + + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x20 + (start << 4)]; + + for(column = start; column < end; column++) + { + atbuf = nt[column]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + } + + /* Merge background layers */ + merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[(reg[12] & 0x08) >> 2], bitmap.viewport.w); +} + +void render_bg_m5_im2_vs(int line) +{ + int column; + uint32 atex, atbuf, *src, *dst; + uint32 v_line, *nt; + + /* Common data */ + int odd = odd_frame; + uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)]; + uint32 yscroll = 0; + uint32 pf_col_mask = playfield_col_mask; + uint32 pf_row_mask = playfield_row_mask; + uint32 pf_shift = playfield_shift; + uint32 *vs = (uint32 *)&vsram[0]; + + /* Window & Plane A */ + int a = (reg[18] & 0x1F) << 3; + int w = (reg[18] >> 7) & 1; + + /* Plane B width */ + int start = 0; + int end = bitmap.viewport.w >> 4; + + /* Plane B horizontal scroll */ +#ifdef LSB_FIRST + uint32 shift = (xscroll >> 16) & 0x0F; + uint32 index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask); +#else + uint32 shift = (xscroll & 0x0F); + uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask); +#endif + + /* Left-most column vertical scrolling when partially shown horizontally (verified on PAL MD2) */ + /* TODO: check on Genesis 3 models since it apparently behaves differently */ + /* In H32 mode, vertical scrolling is disabled, in H40 mode, same value is used for both planes */ + /* See Formula One / Kawasaki Superbike Challenge (H32) & Gynoug / Cutie Suzuki no Ringside Angel (H40) */ + if (reg[12] & 1) + { + yscroll = (vs[19] >> 1) & (vs[19] >> 17); + } + + if(shift) + { + /* Plane B vertical scroll */ + v_line = (line + yscroll) & pf_row_mask; + + /* Plane B name table */ + nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + /* Plane B line buffer */ + dst = (uint32 *)&linebuf[0][0x10 + shift]; + + atbuf = nt[(index - 1) & pf_col_mask]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + else + { + /* Plane B line buffer */ + dst = (uint32 *)&linebuf[0][0x20]; + } + + for(column = 0; column < end; column++, index++) + { + /* Plane B vertical scroll */ +#ifdef LSB_FIRST + v_line = (line + (vs[column] >> 17)) & pf_row_mask; +#else + v_line = (line + (vs[column] >> 1)) & pf_row_mask; +#endif + + /* Plane B name table */ + nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + + if (w == (line >= a)) + { + /* Window takes up entire line */ + a = 0; + w = 1; + } + else + { + /* Window and Plane A share the line */ + a = clip[0].enable; + w = clip[1].enable; + } + + /* Plane A */ + if (a) + { + /* Plane A width */ + start = clip[0].left; + end = clip[0].right; + + /* Plane A horizontal scroll */ +#ifdef LSB_FIRST + shift = (xscroll & 0x0F); + index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask); +#else + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask); +#endif + + if(shift) + { + /* Plane A vertical scroll */ + v_line = (line + yscroll) & pf_row_mask; + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x10 + shift + (start << 4)]; + + /* Window bug */ + if (start) + { + atbuf = nt[index & pf_col_mask]; + } + else + { + atbuf = nt[(index - 1) & pf_col_mask]; + } + + DRAW_COLUMN_IM2(atbuf, v_line) + } + else + { + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x20 + (start << 4)]; + } + + for(column = start; column < end; column++, index++) + { + /* Plane A vertical scroll */ +#ifdef LSB_FIRST + v_line = (line + (vs[column] >> 1)) & pf_row_mask; +#else + v_line = (line + (vs[column] >> 17)) & pf_row_mask; +#endif + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + + /* Window width */ + start = clip[1].left; + end = clip[1].right; + } + + /* Window */ + if (w) + { + /* Window name table */ + nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))]; + + /* Pattern row index */ + v_line = ((line & 7) << 1 | odd) << 3; + + /* Plane A line buffer */ + dst = (uint32 *)&linebuf[1][0x20 + (start << 4)]; + + for(column = start; column < end; column++) + { + atbuf = nt[column]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + } + + /* Merge background layers */ + merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[(reg[12] & 0x08) >> 2], bitmap.viewport.w); +} + +#else + +void render_bg_m5(int line) +{ + int column, start, end; + uint32 atex, atbuf, *src, *dst; + uint32 shift, index, v_line, *nt; + uint8 *lb; + + /* Scroll Planes common data */ + uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)]; + uint32 yscroll = *(uint32 *)&vsram[0]; + uint32 pf_col_mask = playfield_col_mask; + uint32 pf_row_mask = playfield_row_mask; + uint32 pf_shift = playfield_shift; + + /* Number of columns to draw */ + int width = bitmap.viewport.w >> 4; + + /* Layer priority table */ + uint8 *table = lut[(reg[12] & 8) >> 2]; + + /* Window vertical range (cell 0-31) */ + int a = (reg[18] & 0x1F) << 3; + + /* Window position (0=top, 1=bottom) */ + int w = (reg[18] >> 7) & 1; + + /* Test against current line */ + if (w == (line >= a)) + { + /* Window takes up entire line */ + a = 0; + w = 1; + } + else + { + /* Window and Plane A share the line */ + a = clip[0].enable; + w = clip[1].enable; + } + + /* Plane A */ + if (a) + { + /* Plane A width */ + start = clip[0].left; + end = clip[0].right; + + /* Plane A scroll */ +#ifdef LSB_FIRST + shift = (xscroll & 0x0F); + index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask); + v_line = (line + yscroll) & pf_row_mask; +#else + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask); + v_line = (line + (yscroll >> 16)) & pf_row_mask; +#endif + + /* Background line buffer */ + dst = (uint32 *)&linebuf[0][0x20 + (start << 4) + shift]; + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + if(shift) + { + /* Left-most column is partially shown */ + dst -= 4; + + /* Window bug */ + if (start) + { + atbuf = nt[index & pf_col_mask]; + } + else + { + atbuf = nt[(index-1) & pf_col_mask]; + } + + DRAW_COLUMN(atbuf, v_line) + } + + for(column = start; column < end; column++, index++) + { + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN(atbuf, v_line) + } + + /* Window width */ + start = clip[1].left; + end = clip[1].right; + } + else + { + /* Window width */ + start = 0; + end = width; + } + + /* Window Plane */ + if (w) + { + /* Background line buffer */ + dst = (uint32 *)&linebuf[0][0x20 + (start << 4)]; + + /* Window name table */ + nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))]; + + /* Pattern row index */ + v_line = (line & 7) << 3; + + for(column = start; column < end; column++) + { + atbuf = nt[column]; + DRAW_COLUMN(atbuf, v_line) + } + } + + /* Plane B scroll */ +#ifdef LSB_FIRST + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask); + v_line = (line + (yscroll >> 16)) & pf_row_mask; +#else + shift = (xscroll & 0x0F); + index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask); + v_line = (line + yscroll) & pf_row_mask; +#endif + + /* Plane B name table */ + nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + /* Background line buffer */ + lb = &linebuf[0][0x20]; + + if(shift) + { + /* Left-most column is partially shown */ + lb -= (0x10 - shift); + + atbuf = nt[(index-1) & pf_col_mask]; + DRAW_BG_COLUMN(atbuf, v_line, xscroll, yscroll) + } + + for(column = 0; column < width; column++, index++) + { + atbuf = nt[index & pf_col_mask]; + DRAW_BG_COLUMN(atbuf, v_line, xscroll, yscroll) + } +} + +void render_bg_m5_vs(int line) +{ + int column, start, end; + uint32 atex, atbuf, *src, *dst; + uint32 shift, index, v_line, *nt; + uint8 *lb; + + /* Scroll Planes common data */ + uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)]; + uint32 yscroll = 0; + uint32 pf_col_mask = playfield_col_mask; + uint32 pf_row_mask = playfield_row_mask; + uint32 pf_shift = playfield_shift; + uint32 *vs = (uint32 *)&vsram[0]; + + /* Number of columns to draw */ + int width = bitmap.viewport.w >> 4; + + /* Layer priority table */ + uint8 *table = lut[(reg[12] & 8) >> 2]; + + /* Window vertical range (cell 0-31) */ + int a = (reg[18] & 0x1F) << 3; + + /* Window position (0=top, 1=bottom) */ + int w = (reg[18] >> 7) & 1; + + /* Test against current line */ + if (w == (line >= a)) + { + /* Window takes up entire line */ + a = 0; + w = 1; + } + else + { + /* Window and Plane A share the line */ + a = clip[0].enable; + w = clip[1].enable; + } + + /* Left-most column vertical scrolling when partially shown horizontally */ + /* Same value for both planes, only in 40-cell mode, verified on PAL MD2 */ + /* See Gynoug, Cutie Suzuki no Ringside Angel, Formula One, Kawasaki Superbike Challenge */ + if (reg[12] & 1) + { + yscroll = vs[19] & (vs[19] >> 16); + } + + /* Plane A*/ + if (a) + { + /* Plane A width */ + start = clip[0].left; + end = clip[0].right; + + /* Plane A horizontal scroll */ +#ifdef LSB_FIRST + shift = (xscroll & 0x0F); + index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask); +#else + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask); +#endif + + /* Background line buffer */ + dst = (uint32 *)&linebuf[0][0x20 + (start << 4) + shift]; + + if(shift) + { + /* Left-most column is partially shown */ + dst -= 4; + + /* Plane A vertical scroll */ + v_line = (line + yscroll) & pf_row_mask; + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + /* Window bug */ + if (start) + { + atbuf = nt[index & pf_col_mask]; + } + else + { + atbuf = nt[(index-1) & pf_col_mask]; + } + + DRAW_COLUMN(atbuf, v_line) + } + + for(column = start; column < end; column++, index++) + { + /* Plane A vertical scroll */ +#ifdef LSB_FIRST + v_line = (line + vs[column]) & pf_row_mask; +#else + v_line = (line + (vs[column] >> 16)) & pf_row_mask; +#endif + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN(atbuf, v_line) + } + + /* Window width */ + start = clip[1].left; + end = clip[1].right; + } + else + { + /* Window width */ + start = 0; + end = width; + } + + /* Window Plane */ + if (w) + { + /* Background line buffer */ + dst = (uint32 *)&linebuf[0][0x20 + (start << 4)]; + + /* Window name table */ + nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))]; + + /* Pattern row index */ + v_line = (line & 7) << 3; + + for(column = start; column < end; column++) + { + atbuf = nt[column]; + DRAW_COLUMN(atbuf, v_line) + } + } + + /* Plane B horizontal scroll */ +#ifdef LSB_FIRST + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask); +#else + shift = (xscroll & 0x0F); + index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask); +#endif + + /* Background line buffer */ + lb = &linebuf[0][0x20]; + + if(shift) + { + /* Left-most column is partially shown */ + lb -= (0x10 - shift); + + /* Plane B vertical scroll */ + v_line = (line + yscroll) & pf_row_mask; + + /* Plane B name table */ + nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + atbuf = nt[(index-1) & pf_col_mask]; + DRAW_BG_COLUMN(atbuf, v_line, xscroll, yscroll) + } + + for(column = 0; column < width; column++, index++) + { + /* Plane B vertical scroll */ +#ifdef LSB_FIRST + v_line = (line + (vs[column] >> 16)) & pf_row_mask; +#else + v_line = (line + vs[column]) & pf_row_mask; +#endif + + /* Plane B name table */ + nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + atbuf = nt[index & pf_col_mask]; + DRAW_BG_COLUMN(atbuf, v_line, xscroll, yscroll) + } +} + +void render_bg_m5_im2(int line) +{ + int column, start, end; + uint32 atex, atbuf, *src, *dst; + uint32 shift, index, v_line, *nt; + uint8 *lb; + + /* Scroll Planes common data */ + int odd = odd_frame; + uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)]; + uint32 yscroll = *(uint32 *)&vsram[0]; + uint32 pf_col_mask = playfield_col_mask; + uint32 pf_row_mask = playfield_row_mask; + uint32 pf_shift = playfield_shift; + + /* Number of columns to draw */ + int width = bitmap.viewport.w >> 4; + + /* Layer priority table */ + uint8 *table = lut[(reg[12] & 8) >> 2]; + + /* Window vertical range (cell 0-31) */ + int a = (reg[18] & 0x1F) << 3; + + /* Window position (0=top, 1=bottom) */ + int w = (reg[18] >> 7) & 1; + + /* Test against current line */ + if (w == (line >= a)) + { + /* Window takes up entire line */ + a = 0; + w = 1; + } + else + { + /* Window and Plane A share the line */ + a = clip[0].enable; + w = clip[1].enable; + } + + /* Plane A */ + if (a) + { + /* Plane A width */ + start = clip[0].left; + end = clip[0].right; + + /* Plane A scroll */ +#ifdef LSB_FIRST + shift = (xscroll & 0x0F); + index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask); + v_line = (line + (yscroll >> 1)) & pf_row_mask; +#else + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask); + v_line = (line + (yscroll >> 17)) & pf_row_mask; +#endif + + /* Background line buffer */ + dst = (uint32 *)&linebuf[0][0x20 + (start << 4) + shift]; + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + if(shift) + { + /* Left-most column is partially shown */ + dst -= 4; + + /* Window bug */ + if (start) + { + atbuf = nt[index & pf_col_mask]; + } + else + { + atbuf = nt[(index-1) & pf_col_mask]; + } + + DRAW_COLUMN_IM2(atbuf, v_line) + } + + for(column = start; column < end; column++, index++) + { + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + + /* Window width */ + start = clip[1].left; + end = clip[1].right; + } + else + { + /* Window width */ + start = 0; + end = width; + } + + /* Window Plane */ + if (w) + { + /* Background line buffer */ + dst = (uint32 *)&linebuf[0][0x20 + (start << 4)]; + + /* Window name table */ + nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))]; + + /* Pattern row index */ + v_line = ((line & 7) << 1 | odd) << 3; + + for(column = start; column < end; column++) + { + atbuf = nt[column]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + } + + /* Plane B scroll */ +#ifdef LSB_FIRST + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask); + v_line = (line + (yscroll >> 17)) & pf_row_mask; +#else + shift = (xscroll & 0x0F); + index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask); + v_line = (line + (yscroll >> 1)) & pf_row_mask; +#endif + + /* Plane B name table */ + nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + /* Background line buffer */ + lb = &linebuf[0][0x20]; + + if(shift) + { + /* Left-most column is partially shown */ + lb -= (0x10 - shift); + + atbuf = nt[(index-1) & pf_col_mask]; + DRAW_BG_COLUMN_IM2(atbuf, v_line, xscroll, yscroll) + } + + for(column = 0; column < width; column++, index++) + { + atbuf = nt[index & pf_col_mask]; + DRAW_BG_COLUMN_IM2(atbuf, v_line, xscroll, yscroll) + } +} + +void render_bg_m5_im2_vs(int line) +{ + int column, start, end; + uint32 atex, atbuf, *src, *dst; + uint32 shift, index, v_line, *nt; + uint8 *lb; + + /* common data */ + int odd = odd_frame; + uint32 xscroll = *(uint32 *)&vram[hscb + ((line & hscroll_mask) << 2)]; + uint32 yscroll = 0; + uint32 pf_col_mask = playfield_col_mask; + uint32 pf_row_mask = playfield_row_mask; + uint32 pf_shift = playfield_shift; + uint32 *vs = (uint32 *)&vsram[0]; + + /* Number of columns to draw */ + int width = bitmap.viewport.w >> 4; + + /* Layer priority table */ + uint8 *table = lut[(reg[12] & 8) >> 2]; + + /* Window vertical range (cell 0-31) */ + uint32 a = (reg[18] & 0x1F) << 3; + + /* Window position (0=top, 1=bottom) */ + uint32 w = (reg[18] >> 7) & 1; + + /* Test against current line */ + if (w == (line >= a)) + { + /* Window takes up entire line */ + a = 0; + w = 1; + } + else + { + /* Window and Plane A share the line */ + a = clip[0].enable; + w = clip[1].enable; + } + + /* Left-most column vertical scrolling when partially shown horizontally */ + /* Same value for both planes, only in 40-cell mode, verified on PAL MD2 */ + /* See Gynoug, Cutie Suzuki no Ringside Angel, Formula One, Kawasaki Superbike Challenge */ + if (reg[12] & 1) + { + /* only in 40-cell mode, verified on MD2 */ + yscroll = (vs[19] >> 1) & (vs[19] >> 17); + } + + /* Plane A */ + if (a) + { + /* Plane A width */ + start = clip[0].left; + end = clip[0].right; + + /* Plane A horizontal scroll */ +#ifdef LSB_FIRST + shift = (xscroll & 0x0F); + index = pf_col_mask + start + 1 - ((xscroll >> 4) & pf_col_mask); +#else + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + start + 1 - ((xscroll >> 20) & pf_col_mask); +#endif + + /* Background line buffer */ + dst = (uint32 *)&linebuf[0][0x20 + (start << 4) + shift]; + + if(shift) + { + /* Left-most column is partially shown */ + dst -= 4; + + /* Plane A vertical scroll */ + v_line = (line + yscroll) & pf_row_mask; + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + /* Window bug */ + if (start) + { + atbuf = nt[index & pf_col_mask]; + } + else + { + atbuf = nt[(index-1) & pf_col_mask]; + } + + DRAW_COLUMN_IM2(atbuf, v_line) + } + + for(column = start; column < end; column++, index++) + { + /* Plane A vertical scroll */ +#ifdef LSB_FIRST + v_line = (line + (vs[column] >> 1)) & pf_row_mask; +#else + v_line = (line + (vs[column] >> 17)) & pf_row_mask; +#endif + + /* Plane A name table */ + nt = (uint32 *)&vram[ntab + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + atbuf = nt[index & pf_col_mask]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + + /* Window width */ + start = clip[1].left; + end = clip[1].right; + } + else + { + /* Window width */ + start = 0; + end = width; + } + + /* Window Plane */ + if (w) + { + /* Background line buffer */ + dst = (uint32 *)&linebuf[0][0x20 + (start << 4)]; + + /* Window name table */ + nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))]; + + /* Pattern row index */ + v_line = ((line & 7) << 1 | odd) << 3; + + for(column = start; column < end; column++) + { + atbuf = nt[column]; + DRAW_COLUMN_IM2(atbuf, v_line) + } + } + + /* Plane B horizontal scroll */ +#ifdef LSB_FIRST + shift = (xscroll >> 16) & 0x0F; + index = pf_col_mask + 1 - ((xscroll >> 20) & pf_col_mask); +#else + shift = (xscroll & 0x0F); + index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask); +#endif + + /* Background line buffer */ + lb = &linebuf[0][0x20]; + + if(shift) + { + /* Left-most column is partially shown */ + lb -= (0x10 - shift); + + /* Plane B vertical scroll */ + v_line = (line + yscroll) & pf_row_mask; + + /* Plane B name table */ + nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + atbuf = nt[(index-1) & pf_col_mask]; + DRAW_BG_COLUMN_IM2(atbuf, v_line, xscroll, yscroll) + } + + for(column = 0; column < width; column++, index++) + { + /* Plane B vertical scroll */ +#ifdef LSB_FIRST + v_line = (line + (vs[column] >> 17)) & pf_row_mask; +#else + v_line = (line + (vs[column] >> 1)) & pf_row_mask; +#endif + + /* Plane B name table */ + nt = (uint32 *)&vram[ntbb + (((v_line >> 3) << pf_shift) & 0x1FC0)]; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + atbuf = nt[index & pf_col_mask]; + DRAW_BG_COLUMN_IM2(atbuf, v_line, xscroll, yscroll) + } +} +#endif + + +/*--------------------------------------------------------------------------*/ +/* Sprite layer rendering functions */ +/*--------------------------------------------------------------------------*/ + +void render_obj_tms(int line) +{ + int x, start, end; + uint8 *lb, *sg; + uint8 color, pattern[2]; + uint16 temp; + + /* Sprite list for current line */ + object_info_t *object_info = obj_info[line]; + int count = object_count[line]; + + /* Default sprite width (8 pixels) */ + int width = 8; + + /* Adjust width for 16x16 sprites */ + width <<= ((reg[1] & 0x02) >> 1); + + /* Adjust width for zoomed sprites */ + width <<= (reg[1] & 0x01); + + /* Latch SOVR flag from previous line to VDP status */ + status |= spr_ovr; + + /* Clear SOVR flag for current line */ + spr_ovr = 0; + + /* Draw sprites in front-to-back order */ + while (count--) + { + /* Sprite X position */ + start = object_info->xpos; + + /* Sprite Color + Early Clock bit */ + color = object_info->size; + + /* X position shift (32 pixels) */ + start -= ((color & 0x80) >> 2); + + /* Pointer to line buffer */ + lb = &linebuf[0][0x20 + start]; + + if ((start + width) > 256) + { + /* Clip sprites on right edge */ + end = 256 - start; + start = 0; + } + else + { + end = width; + + if (start < 0) + { + /* Clip sprites on left edge */ + start = 0 - start; + } + else + { + start = 0; + } + } + + /* Sprite Color (0-15) */ + color &= 0x0F; + + /* Sprite Pattern Name */ + temp = object_info->attr; + + /* Mask two LSB for 16x16 sprites */ + temp &= ~((reg[1] & 0x02) >> 0); + temp &= ~((reg[1] & 0x02) >> 1); + + /* Pointer to sprite generator table */ + sg = (uint8 *)&vram[((reg[6] << 11) & 0x3800) | (temp << 3) | object_info->ypos]; + + /* Sprite Pattern data (2 x 8 pixels) */ + pattern[0] = sg[0x00]; + pattern[1] = sg[0x10]; + + if (reg[1] & 0x01) + { + /* Zoomed sprites are rendered at half speed */ + for (x=start; x> 4) & 1]; + temp = (temp >> (7 - ((x >> 1) & 7))) & 0x01; + temp = temp * color; + temp |= (lb[x] << 8); + lb[x] = lut[5][temp]; + status |= ((temp & 0x8000) >> 10); + temp &= 0x00FF; + temp |= (lb[x+1] << 8); + lb[x+1] = lut[5][temp]; + status |= ((temp & 0x8000) >> 10); + } + } + else + { + /* Normal sprites */ + for (x=start; x> 3) & 1]; + temp = (temp >> (7 - (x & 7))) & 0x01; + temp = temp * color; + temp |= (lb[x] << 8); + lb[x] = lut[5][temp]; + status |= ((temp & 0x8000) >> 10); + } + } + + /* Next sprite entry */ + object_info++; + } + + /* handle Game Gear reduced screen (160x144) */ + if ((system_hw == SYSTEM_GG) && !config.gg_extra && (v_counter < bitmap.viewport.h)) + { + int line = v_counter - (bitmap.viewport.h - 144) / 2; + if ((line < 0) || (line >= 144)) + { + memset(&linebuf[0][0x20], 0x40, 256); + } + else + { + if (bitmap.viewport.x > 0) + { + memset(&linebuf[0][0x20], 0x40, 48); + memset(&linebuf[0][0x20+48+160], 0x40, 48); + } + } + } +} + +void render_obj_m4(int line) +{ + int i, xpos, end; + uint8 *src, *lb; + uint16 temp; + + /* Sprite list for current line */ + object_info_t *object_info = obj_info[line]; + int count = object_count[line]; + + /* Default sprite width */ + int width = 8; + + /* Sprite Generator address mask (LSB is masked for 8x16 sprites) */ + uint16 sg_mask = (~0x1C0 ^ (reg[6] << 6)) & (~((reg[1] & 0x02) >> 1)); + + /* Zoomed sprites (not working on Genesis VDP) */ + if (system_hw < SYSTEM_MD) + { + width <<= (reg[1] & 0x01); + } + + /* Unused bits used as a mask on 315-5124 VDP only */ + if (system_hw > SYSTEM_SMS) + { + sg_mask |= 0xC0; + } + + /* Latch SOVR flag from previous line to VDP status */ + status |= spr_ovr; + + /* Clear SOVR flag for current line */ + spr_ovr = 0; + + /* Draw sprites in front-to-back order */ + while (count--) + { + /* Sprite pattern index */ + temp = (object_info->attr | 0x100) & sg_mask; + + /* Pointer to pattern cache line */ + src = (uint8 *)&bg_pattern_cache[(temp << 6) | (object_info->ypos << 3)]; + + /* Sprite X position */ + xpos = object_info->xpos; + + /* X position shift */ + xpos -= (reg[0] & 0x08); + + if (xpos < 0) + { + /* Clip sprites on left edge */ + src = src - xpos; + end = xpos + width; + xpos = 0; + } + else if ((xpos + width) > 256) + { + /* Clip sprites on right edge */ + end = 256 - xpos; + } + else + { + /* Sprite maximal width */ + end = width; + } + + /* Pointer to line buffer */ + lb = &linebuf[0][0x20 + xpos]; + + if (width > 8) + { + /* Draw sprite pattern (zoomed sprites are rendered at half speed) */ + DRAW_SPRITE_TILE_ACCURATE_2X(end,0,lut[5]) + + /* 315-5124 VDP specific */ + if (system_hw < SYSTEM_SMS2) + { + /* only 4 first sprites can be zoomed */ + if (count == (object_count[line] - 4)) + { + /* Set default width for remaining sprites */ + width = 8; + } + } + } + else + { + /* Draw sprite pattern */ + DRAW_SPRITE_TILE_ACCURATE(end,0,lut[5]) + } + + /* Next sprite entry */ + object_info++; + } + + /* handle Game Gear reduced screen (160x144) */ + if ((system_hw == SYSTEM_GG) && !config.gg_extra && (v_counter < bitmap.viewport.h)) + { + int line = v_counter - (bitmap.viewport.h - 144) / 2; + if ((line < 0) || (line >= 144)) + { + memset(&linebuf[0][0x20], 0x40, 256); + } + else + { + if (bitmap.viewport.x > 0) + { + memset(&linebuf[0][0x20], 0x40, 48); + memset(&linebuf[0][0x20+48+160], 0x40, 48); + } + } + } +} + +void render_obj_m5(int line) +{ + int i, column; + int xpos, width; + int pixelcount = 0; + int masked = 0; + + uint8 *src, *s, *lb; + uint32 temp, v_line; + uint32 attr, name, atex; + + /* Sprite list for current line */ + object_info_t *object_info = obj_info[line]; + int count = object_count[line]; + + /* Draw sprites in front-to-back order */ + while (count--) + { + /* Sprite X position */ + xpos = object_info->xpos; + + /* Sprite masking */ + if (xpos) + { + /* Requires at least one sprite with xpos > 0 */ + spr_ovr = 1; + } + else if (spr_ovr) + { + /* Remaining sprites are not drawn */ + masked = 1; + } + + /* Display area offset */ + xpos = xpos - 0x80; + + /* Sprite size */ + temp = object_info->size; + + /* Sprite width */ + width = 8 + ((temp & 0x0C) << 1); + + /* Update pixel count (off-screen sprites are included) */ + pixelcount += width; + + /* Is sprite across visible area ? */ + if (((xpos + width) > 0) && (xpos < bitmap.viewport.w) && !masked) + { + /* Sprite attributes */ + attr = object_info->attr; + + /* Sprite vertical offset */ + v_line = object_info->ypos; + + /* Sprite priority + palette bits */ + atex = (attr >> 9) & 0x70; + + /* Pattern name base */ + name = attr & 0x07FF; + + /* Mask vflip/hflip */ + attr &= 0x1800; + + /* Pointer into pattern name offset look-up table */ + s = &name_lut[((attr >> 3) & 0x300) | (temp << 4) | ((v_line & 0x18) >> 1)]; + + /* Pointer into line buffer */ + lb = &linebuf[0][0x20 + xpos]; + + /* Max. number of sprite pixels rendered per line */ + if (pixelcount > max_sprite_pixels) + { + /* Adjust number of pixels to draw */ + width -= (pixelcount - max_sprite_pixels); + } + + /* Number of tiles to draw */ + width = width >> 3; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + /* Draw sprite patterns */ + for (column = 0; column < width; column++, lb+=8) + { + temp = attr | ((name + s[column]) & 0x07FF); + src = &bg_pattern_cache[(temp << 6) | (v_line)]; + DRAW_SPRITE_TILE(8,atex,lut[1]) + } + } + + /* Sprite limit */ + if (pixelcount >= max_sprite_pixels) + { + /* Sprite masking is effective on next line if max pixel width is reached */ + spr_ovr = (pixelcount >= bitmap.viewport.w); + + /* Stop sprite rendering */ + return; + } + + /* Next sprite entry */ + object_info++; + } + + /* Clear sprite masking for next line */ + spr_ovr = 0; +} + +void render_obj_m5_ste(int line) +{ + int i, column; + int xpos, width; + int pixelcount = 0; + int masked = 0; + + uint8 *src, *s, *lb; + uint32 temp, v_line; + uint32 attr, name, atex; + + /* Sprite list for current line */ + object_info_t *object_info = obj_info[line]; + int count = object_count[line]; + + /* Clear sprite line buffer */ + memset(&linebuf[1][0], 0, bitmap.viewport.w + 0x40); + + /* Draw sprites in front-to-back order */ + while (count--) + { + /* Sprite X position */ + xpos = object_info->xpos; + + /* Sprite masking */ + if (xpos) + { + /* Requires at least one sprite with xpos > 0 */ + spr_ovr = 1; + } + else if (spr_ovr) + { + /* Remaining sprites are not drawn */ + masked = 1; + } + + /* Display area offset */ + xpos = xpos - 0x80; + + /* Sprite size */ + temp = object_info->size; + + /* Sprite width */ + width = 8 + ((temp & 0x0C) << 1); + + /* Update pixel count (off-screen sprites are included) */ + pixelcount += width; + + /* Is sprite across visible area ? */ + if (((xpos + width) > 0) && (xpos < bitmap.viewport.w) && !masked) + { + /* Sprite attributes */ + attr = object_info->attr; + + /* Sprite vertical offset */ + v_line = object_info->ypos; + + /* Sprite priority + palette bits */ + atex = (attr >> 9) & 0x70; + + /* Pattern name base */ + name = attr & 0x07FF; + + /* Mask vflip/hflip */ + attr &= 0x1800; + + /* Pointer into pattern name offset look-up table */ + s = &name_lut[((attr >> 3) & 0x300) | (temp << 4) | ((v_line & 0x18) >> 1)]; + + /* Pointer into line buffer */ + lb = &linebuf[1][0x20 + xpos]; + + /* Adjust number of pixels to draw for sprite limit */ + if (pixelcount > max_sprite_pixels) + { + width -= (pixelcount - max_sprite_pixels); + } + + /* Number of tiles to draw */ + width = width >> 3; + + /* Pattern row index */ + v_line = (v_line & 7) << 3; + + /* Draw sprite patterns */ + for (column = 0; column < width; column++, lb+=8) + { + temp = attr | ((name + s[column]) & 0x07FF); + src = &bg_pattern_cache[(temp << 6) | (v_line)]; + DRAW_SPRITE_TILE(8,atex,lut[3]) + } + } + + /* Sprite limit */ + if (pixelcount >= max_sprite_pixels) + { + /* Sprite masking is effective on next line if max pixel width is reached */ + spr_ovr = (pixelcount >= bitmap.viewport.w); + + /* Merge background & sprite layers */ + merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[4], bitmap.viewport.w); + + /* Stop sprite rendering */ + return; + } + + /* Next sprite entry */ + object_info++; + } + + /* Clear sprite masking for next line */ + spr_ovr = 0; + + /* Merge background & sprite layers */ + merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[4], bitmap.viewport.w); +} + +void render_obj_m5_im2(int line) +{ + int i, column; + int xpos, width; + int pixelcount = 0; + int masked = 0; + int odd = odd_frame; + + uint8 *src, *s, *lb; + uint32 temp, v_line; + uint32 attr, name, atex; + + /* Sprite list for current line */ + object_info_t *object_info = obj_info[line]; + int count = object_count[line]; + + /* Draw sprites in front-to-back order */ + while (count--) + { + /* Sprite X position */ + xpos = object_info->xpos; + + /* Sprite masking */ + if (xpos) + { + /* Requires at least one sprite with xpos > 0 */ + spr_ovr = 1; + } + else if (spr_ovr) + { + /* Remaining sprites are not drawn */ + masked = 1; + } + + /* Display area offset */ + xpos = xpos - 0x80; + + /* Sprite size */ + temp = object_info->size; + + /* Sprite width */ + width = 8 + ((temp & 0x0C) << 1); + + /* Update pixel count (off-screen sprites are included) */ + pixelcount += width; + + /* Is sprite across visible area ? */ + if (((xpos + width) > 0) && (xpos < bitmap.viewport.w) && !masked) + { + /* Sprite attributes */ + attr = object_info->attr; + + /* Sprite y offset */ + v_line = object_info->ypos; + + /* Sprite priority + palette bits */ + atex = (attr >> 9) & 0x70; + + /* Pattern name base */ + name = attr & 0x03FF; + + /* Mask vflip/hflip */ + attr &= 0x1800; + + /* Pattern name offset lookup table */ + s = &name_lut[((attr >> 3) & 0x300) | (temp << 4) | ((v_line & 0x18) >> 1)]; + + /* Pointer into line buffer */ + lb = &linebuf[0][0x20 + xpos]; + + /* Adjust width for sprite limit */ + if (pixelcount > max_sprite_pixels) + { + width -= (pixelcount - max_sprite_pixels); + } + + /* Number of tiles to draw */ + width = width >> 3; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + /* Render sprite patterns */ + for(column = 0; column < width; column ++, lb+=8) + { + temp = attr | (((name + s[column]) & 0x3ff) << 1); + src = &bg_pattern_cache[((temp << 6) | (v_line)) ^ ((attr & 0x1000) >> 6)]; + DRAW_SPRITE_TILE(8,atex,lut[1]) + } + } + + /* Sprite Limit */ + if (pixelcount >= max_sprite_pixels) + { + /* Sprite masking is effective on next line if max pixel width is reached */ + spr_ovr = (pixelcount >= bitmap.viewport.w); + + /* Stop sprite rendering */ + return; + } + + /* Next sprite entry */ + object_info++; + } + + /* Clear sprite masking for next line */ + spr_ovr = 0; +} + +void render_obj_m5_im2_ste(int line) +{ + int i, column; + int xpos, width; + int pixelcount = 0; + int masked = 0; + int odd = odd_frame; + + uint8 *src, *s, *lb; + uint32 temp, v_line; + uint32 attr, name, atex; + + /* Sprite list for current line */ + object_info_t *object_info = obj_info[line]; + int count = object_count[line]; + + /* Clear sprite line buffer */ + memset(&linebuf[1][0], 0, bitmap.viewport.w + 0x40); + + /* Draw sprites in front-to-back order */ + while (count--) + { + /* Sprite X position */ + xpos = object_info->xpos; + + /* Sprite masking */ + if (xpos) + { + /* Requires at least one sprite with xpos > 0 */ + spr_ovr = 1; + } + else if (spr_ovr) + { + /* Remaining sprites are not drawn */ + masked = 1; + } + + /* Display area offset */ + xpos = xpos - 0x80; + + /* Sprite size */ + temp = object_info->size; + + /* Sprite width */ + width = 8 + ((temp & 0x0C) << 1); + + /* Update pixel count (off-screen sprites are included) */ + pixelcount += width; + + /* Is sprite across visible area ? */ + if (((xpos + width) > 0) && (xpos < bitmap.viewport.w) && !masked) + { + /* Sprite attributes */ + attr = object_info->attr; + + /* Sprite y offset */ + v_line = object_info->ypos; + + /* Sprite priority + palette bits */ + atex = (attr >> 9) & 0x70; + + /* Pattern name base */ + name = attr & 0x03FF; + + /* Mask vflip/hflip */ + attr &= 0x1800; + + /* Pattern name offset lookup table */ + s = &name_lut[((attr >> 3) & 0x300) | (temp << 4) | ((v_line & 0x18) >> 1)]; + + /* Pointer into line buffer */ + lb = &linebuf[1][0x20 + xpos]; + + /* Adjust width for sprite limit */ + if (pixelcount > max_sprite_pixels) + { + width -= (pixelcount - max_sprite_pixels); + } + + /* Number of tiles to draw */ + width = width >> 3; + + /* Pattern row index */ + v_line = (((v_line & 7) << 1) | odd) << 3; + + /* Render sprite patterns */ + for(column = 0; column < width; column ++, lb+=8) + { + temp = attr | (((name + s[column]) & 0x3ff) << 1); + src = &bg_pattern_cache[((temp << 6) | (v_line)) ^ ((attr & 0x1000) >> 6)]; + DRAW_SPRITE_TILE(8,atex,lut[3]) + } + } + + /* Sprite Limit */ + if (pixelcount >= max_sprite_pixels) + { + /* Sprite masking is effective on next line if max pixel width is reached */ + spr_ovr = (pixelcount >= bitmap.viewport.w); + + /* Merge background & sprite layers */ + merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[4], bitmap.viewport.w); + + /* Stop sprite rendering */ + return; + } + + /* Next sprite entry */ + object_info++; + } + + /* Clear sprite masking for next line */ + spr_ovr = 0; + + /* Merge background & sprite layers */ + merge(&linebuf[1][0x20], &linebuf[0][0x20], &linebuf[0][0x20], lut[4], bitmap.viewport.w); +} + + +/*--------------------------------------------------------------------------*/ +/* Sprites Parsing functions */ +/*--------------------------------------------------------------------------*/ + +void parse_satb_tms(int line) +{ + int i = 0; + + /* Sprite counter (4 max. per line) */ + int count = 0; + + /* no sprites in Text modes */ + if (!(reg[1] & 0x10)) + { + /* Y position */ + int ypos; + + /* Sprite list for next line */ + object_info_t *object_info = obj_info[(line + 1) & 1]; + + /* Pointer to sprite attribute table */ + uint8 *st = &vram[(reg[5] << 7) & 0x3F80]; + + /* Sprite height (8 pixels by default) */ + int height = 8; + + /* Adjust height for 16x16 sprites */ + height <<= ((reg[1] & 0x02) >> 1); + + /* Adjust height for zoomed sprites */ + height <<= (reg[1] & 0x01); + + /* Parse Sprite Table (32 entries) */ + do + { + /* Sprite Y position */ + ypos = st[i << 2]; + + /* Check end of sprite list marker */ + if (ypos == 0xD0) + { + break; + } + + /* Wrap Y coordinate for sprites > 256-32 */ + if (ypos >= 224) + { + ypos -= 256; + } + + /* Y range */ + ypos = line - ypos; + + /* Sprite is visible on this line ? */ + if ((ypos >= 0) && (ypos < height)) + { + /* Sprite overflow */ + if (count == 4) + { + /* Flag is set only during active area */ + if (line < bitmap.viewport.h) + { + spr_ovr = 0x40; + } + break; + } + + /* Adjust Y range back for zoomed sprites */ + ypos >>= (reg[1] & 0x01); + + /* Store sprite attributes for later processing */ + object_info->ypos = ypos; + object_info->xpos = st[(i << 2) + 1]; + object_info->attr = st[(i << 2) + 2]; + object_info->size = st[(i << 2) + 3]; + + /* Increment Sprite count */ + ++count; + + /* Next sprite entry */ + object_info++; + } + } + while (++i < 32); + } + + /* Update sprite count for next line */ + object_count[(line + 1) & 1] = count; + + /* Insert number of last sprite entry processed */ + status = (status & 0xE0) | (i & 0x1F); +} + +void parse_satb_m4(int line) +{ + int i = 0; + uint8 *st; + + /* Sprite counter (8 max. per line) */ + int count = 0; + + /* Y position */ + int ypos; + + /* Sprite list for next line */ + object_info_t *object_info = obj_info[(line + 1) & 1]; + + /* Sprite height (8x8 or 8x16) */ + int height = 8 + ((reg[1] & 0x02) << 2); + + /* Sprite attribute table address mask */ + uint16 st_mask = ~0x3F80 ^ (reg[5] << 7); + + /* Unused bits used as a mask on 315-5124 VDP only */ + if (system_hw > SYSTEM_SMS) + { + st_mask |= 0x80; + } + + /* Pointer to sprite attribute table */ + st = &vram[st_mask & 0x3F00]; + + /* Parse Sprite Table (64 entries) */ + do + { + /* Sprite Y position */ + ypos = st[i]; + + /* Check end of sprite list marker */ + if (ypos == (bitmap.viewport.h + 16)) + { + break; + } + + /* Wrap Y coordinate for sprites > 256-16 */ + if (ypos >= 240) + { + ypos -= 256; + } + + /* Y range */ + ypos = line - ypos; + + /* Adjust Y range for zoomed sprites (not working on Mega Drive VDP) */ + if (system_hw < SYSTEM_MD) + { + ypos >>= (reg[1] & 0x01); + } + + /* Check if sprite is visible on this line */ + if ((ypos >= 0) && (ypos < height)) + { + /* Sprite overflow */ + if (count == 8) + { + /* Flag is set only during active area */ + if ((line >= 0) && (line < bitmap.viewport.h)) + { + spr_ovr = 0x40; + } + break; + } + + /* Store sprite attributes for later processing */ + object_info->ypos = ypos; + object_info->xpos = st[(0x80 + (i << 1)) & st_mask]; + object_info->attr = st[(0x81 + (i << 1)) & st_mask]; + + /* Increment Sprite count */ + ++count; + + /* Next sprite entry */ + object_info++; + } + } + while (++i < 64); + + /* Update sprite count for next line */ + object_count[(line + 1) & 1] = count; +} + +void parse_satb_m5(int line) +{ + /* Y position */ + int ypos; + + /* Sprite height (8,16,24,32 pixels)*/ + int height; + + /* Sprite size data */ + int size; + + /* Sprite link data */ + int link = 0; + + /* Sprite counter */ + int count = 0; + + /* max. number of rendered sprites (16 or 20 sprites per line by default) */ + int max = bitmap.viewport.w >> 4; + + /* max. number of parsed sprites (64 or 80 sprites per line by default) */ + int total = max_sprite_pixels >> 2; + + /* Pointer to sprite attribute table */ + uint16 *p = (uint16 *) &vram[satb]; + + /* Pointer to internal RAM */ + uint16 *q = (uint16 *) &sat[0]; + + /* Sprite list for next line */ + object_info_t *object_info = obj_info[(line + 1) & 1]; + + /* Adjust line offset */ + line += 0x81; + + do + { + /* Read Y position & size from internal SAT */ + ypos = (q[link] >> im2_flag) & 0x1FF; + size = q[link + 1] >> 8; + + /* Sprite height */ + height = 8 + ((size & 3) << 3); + + /* Y range */ + ypos = line - ypos; + + /* Sprite is visble on this line ? */ + if ((ypos >= 0) && (ypos < height)) + { + /* Sprite overflow */ + if (count == max) + { + status |= 0x40; + break; + } + + /* Update sprite list (only name, attribute & xpos are parsed from VRAM) */ + object_info->attr = p[link + 2]; + object_info->xpos = p[link + 3] & 0x1ff; + object_info->ypos = ypos; + object_info->size = size & 0x0f; + + /* Increment Sprite count */ + ++count; + + /* Next sprite entry */ + object_info++; + } + + /* Read link data from internal SAT */ + link = (q[link + 1] & 0x7F) << 2; + + /* Last sprite */ + if (link == 0) break; + } + while (--total); + + /* Update sprite count for next line (line value already incremented) */ + object_count[line & 1] = count; +} + + +/*--------------------------------------------------------------------------*/ +/* Pattern cache update function */ +/*--------------------------------------------------------------------------*/ + +void update_bg_pattern_cache_m4(int index) +{ + int i; + uint8 x, y, c; + uint8 *dst; + uint16 name, bp01, bp23; + uint32 bp; + + for(i = 0; i < index; i++) + { + /* Get modified pattern name index */ + name = bg_name_list[i]; + + /* Check modified lines */ + for(y = 0; y < 8; y++) + { + if(bg_name_dirty[name] & (1 << y)) + { + /* Pattern cache base address */ + dst = &bg_pattern_cache[name << 6]; + + /* Byteplane data */ + bp01 = *(uint16 *)&vram[(name << 5) | (y << 2) | (0)]; + bp23 = *(uint16 *)&vram[(name << 5) | (y << 2) | (2)]; + + /* Convert to pixel line data (4 bytes = 8 pixels)*/ + /* (msb) p7p6 p5p4 p3p2 p1p0 (lsb) */ + bp = (bp_lut[bp01] >> 2) | (bp_lut[bp23]); + + /* Update cached line (8 pixels = 8 bytes) */ + for(x = 0; x < 8; x++) + { + /* Extract pixel data */ + c = bp & 0x0F; + + /* Pattern cache data (one pattern = 8 bytes) */ + /* byte0 <-> p0 p1 p2 p3 p4 p5 p6 p7 <-> byte7 (hflip = 0) */ + /* byte0 <-> p7 p6 p5 p4 p3 p2 p1 p0 <-> byte7 (hflip = 1) */ + dst[0x00000 | (y << 3) | (x)] = (c); /* vflip=0 & hflip=0 */ + dst[0x08000 | (y << 3) | (x ^ 7)] = (c); /* vflip=0 & hflip=1 */ + dst[0x10000 | ((y ^ 7) << 3) | (x)] = (c); /* vflip=1 & hflip=0 */ + dst[0x18000 | ((y ^ 7) << 3) | (x ^ 7)] = (c); /* vflip=1 & hflip=1 */ + + /* Next pixel */ + bp = bp >> 4; + } + } + } + + /* Clear modified pattern flag */ + bg_name_dirty[name] = 0; + } +} + +void update_bg_pattern_cache_m5(int index) +{ + int i; + uint8 x, y, c; + uint8 *dst; + uint16 name; + uint32 bp; + + for(i = 0; i < index; i++) + { + /* Get modified pattern name index */ + name = bg_name_list[i]; + + /* Check modified lines */ + for(y = 0; y < 8; y ++) + { + if(bg_name_dirty[name] & (1 << y)) + { + /* Pattern cache base address */ + dst = &bg_pattern_cache[name << 6]; + + /* Byteplane data (one pattern = 4 bytes) */ + /* LIT_ENDIAN: byte0 (lsb) p2p3 p0p1 p6p7 p4p5 (msb) byte3 */ + /* BIG_ENDIAN: byte0 (msb) p0p1 p2p3 p4p5 p6p7 (lsb) byte3 */ + bp = *(uint32 *)&vram[(name << 5) | (y << 2)]; + + /* Update cached line (8 pixels = 8 bytes) */ + for(x = 0; x < 8; x ++) + { + /* Extract pixel data */ + c = bp & 0x0F; + + /* Pattern cache data (one pattern = 8 bytes) */ + /* byte0 <-> p0 p1 p2 p3 p4 p5 p6 p7 <-> byte7 (hflip = 0) */ + /* byte0 <-> p7 p6 p5 p4 p3 p2 p1 p0 <-> byte7 (hflip = 1) */ +#ifdef LSB_FIRST + /* Byteplane data = (msb) p4p5 p6p7 p0p1 p2p3 (lsb) */ + dst[0x00000 | (y << 3) | (x ^ 3)] = (c); /* vflip=0, hflip=0 */ + dst[0x20000 | (y << 3) | (x ^ 4)] = (c); /* vflip=0, hflip=1 */ + dst[0x40000 | ((y ^ 7) << 3) | (x ^ 3)] = (c); /* vflip=1, hflip=0 */ + dst[0x60000 | ((y ^ 7) << 3) | (x ^ 4)] = (c); /* vflip=1, hflip=1 */ +#else + /* Byteplane data = (msb) p0p1 p2p3 p4p5 p6p7 (lsb) */ + dst[0x00000 | (y << 3) | (x ^ 7)] = (c); /* vflip=0, hflip=0 */ + dst[0x20000 | (y << 3) | (x)] = (c); /* vflip=0, hflip=1 */ + dst[0x40000 | ((y ^ 7) << 3) | (x ^ 7)] = (c); /* vflip=1, hflip=0 */ + dst[0x60000 | ((y ^ 7) << 3) | (x)] = (c); /* vflip=1, hflip=1 */ +#endif + /* Next pixel */ + bp = bp >> 4; + } + } + } + + /* Clear modified pattern flag */ + bg_name_dirty[name] = 0; + } +} + + +/*--------------------------------------------------------------------------*/ +/* Window & Plane A clipping update function (Mode 5) */ +/*--------------------------------------------------------------------------*/ + +void window_clip(unsigned int data, unsigned int sw) +{ + /* Window size and invert flags */ + int hp = (data & 0x1f); + int hf = (data >> 7) & 1; + + /* Perform horizontal clipping; the results are applied in reverse + if the horizontal inversion flag is set + */ + int a = hf; + int w = hf ^ 1; + + /* Display width (16 or 20 columns) */ + sw = 16 + (sw << 2); + + if(hp) + { + if(hp > sw) + { + /* Plane W takes up entire line */ + clip[w].left = 0; + clip[w].right = sw; + clip[w].enable = 1; + clip[a].enable = 0; + } + else + { + /* Plane W takes left side, Plane A takes right side */ + clip[w].left = 0; + clip[a].right = sw; + clip[a].left = clip[w].right = hp; + clip[0].enable = clip[1].enable = 1; + } + } + else + { + /* Plane A takes up entire line */ + clip[a].left = 0; + clip[a].right = sw; + clip[a].enable = 1; + clip[w].enable = 0; + } +} + + +/*--------------------------------------------------------------------------*/ +/* Init, reset routines */ +/*--------------------------------------------------------------------------*/ + +void render_init(void) +{ + int bx, ax; + + /* Initialize layers priority pixel look-up tables */ + uint16 index; + for (bx = 0; bx < 0x100; bx++) + { + for (ax = 0; ax < 0x100; ax++) + { + index = (bx << 8) | (ax); + + lut[0][index] = make_lut_bg(bx, ax); + lut[1][index] = make_lut_bgobj(bx, ax); + lut[2][index] = make_lut_bg_ste(bx, ax); + lut[3][index] = make_lut_obj(bx, ax); + lut[4][index] = make_lut_bgobj_ste(bx, ax); + lut[5][index] = make_lut_bgobj_m4(bx,ax); + } + } + + /* Initialize pixel color look-up tables */ + palette_init(); + + /* Make sprite pattern name index look-up table (Mode 5) */ + make_name_lut(); + + /* Make bitplane to pixel look-up table (Mode 4) */ + make_bp_lut(); +} + +void render_reset(void) +{ + /* Clear display bitmap */ + memset(bitmap.data, 0, bitmap.pitch * bitmap.height); + + /* Clear line buffers */ + memset(linebuf, 0, sizeof(linebuf)); + + /* Clear color palettes */ + memset(pixel, 0, sizeof(pixel)); + + /* Clear pattern cache */ + memset ((char *) bg_pattern_cache, 0, sizeof (bg_pattern_cache)); + + /* Reset Sprite infos */ + spr_ovr = spr_col = object_count[0] = object_count[1] = 0; +} + + +/*--------------------------------------------------------------------------*/ +/* Line rendering functions */ +/*--------------------------------------------------------------------------*/ + +void render_line(int line) +{ + /* Check display status */ + if (reg[1] & 0x40) + { + /* Update pattern cache */ + if (bg_list_index) + { + update_bg_pattern_cache(bg_list_index); + bg_list_index = 0; + } + + /* Render BG layer(s) */ + render_bg(line); + + /* Render sprite layer */ + render_obj(line & 1); + + /* Left-most column blanking */ + if (reg[0] & 0x20) + { + if (system_hw > SYSTEM_SG) + { + memset(&linebuf[0][0x20], 0x40, 8); + } + } + + /* Parse sprites for next line */ + if (line < (bitmap.viewport.h - 1)) + { + parse_satb(line); + } + + /* Horizontal borders */ + if (bitmap.viewport.x > 0) + { + memset(&linebuf[0][0x20 - bitmap.viewport.x], 0x40, bitmap.viewport.x); + memset(&linebuf[0][0x20 + bitmap.viewport.w], 0x40, bitmap.viewport.x); + } + } + else + { + /* Master System & Game Gear VDP specific */ + if (system_hw < SYSTEM_MD) + { + /* Update SOVR flag */ + status |= spr_ovr; + spr_ovr = 0; + + /* Sprites are still parsed when display is disabled */ + parse_satb(line); + } + + /* Blanked line */ + memset(&linebuf[0][0x20 - bitmap.viewport.x], 0x40, bitmap.viewport.w + 2*bitmap.viewport.x); + } + + /* Pixel color remapping */ + remap_line(line); +} + +void blank_line(int line, int offset, int width) +{ + memset(&linebuf[0][0x20 + offset], 0x40, width); + remap_line(line); +} + +void remap_line(int line) +{ + /* Line width */ + int width = bitmap.viewport.w + 2*bitmap.viewport.x; + + /* Pixel line buffer */ + uint8 *src = &linebuf[0][0x20 - bitmap.viewport.x]; + + /* Adjust line offset in framebuffer */ + line = (line + bitmap.viewport.y) % lines_per_frame; + + /* Take care of Game Gear reduced screen when overscan is disabled */ + if (line < 0) return; + + /* Adjust for interlaced output */ + if (interlaced && config.render) + { + line = (line * 2) + odd_frame; + } + + /* NTSC Filter (only supported for 15 or 16-bit pixels rendering) */ +#if defined(USE_15BPP_RENDERING) || defined(USE_16BPP_RENDERING) + if (config.ntsc) + { + if (reg[12] & 0x01) + { + md_ntsc_blit(md_ntsc, ( MD_NTSC_IN_T const * )pixel, src, width, line); + } + else + { + sms_ntsc_blit(sms_ntsc, ( SMS_NTSC_IN_T const * )pixel, src, width, line); + } + } + else +#endif + { + /* Convert VDP pixel data to output pixel format */ +#ifdef CUSTOM_BLITTER + CUSTOM_BLITTER(line, width, pixel, src) +#else + PIXEL_OUT_T *dst =((PIXEL_OUT_T *)&bitmap.data[(line * bitmap.pitch)]); + do + { + *dst++ = pixel[*src++]; + } + while (--width); +#endif + } +} diff --git a/genplus-gx/core/vdp_render.h b/genplus-gx/core/vdp_render.h new file mode 100644 index 0000000000..9ce924c84a --- /dev/null +++ b/genplus-gx/core/vdp_render.h @@ -0,0 +1,88 @@ +/*************************************************************************************** + * Genesis Plus + * Video Display Processor (Modes 0, 1, 2, 3, 4 & 5 rendering) + * + * Support for SG-1000, Master System (315-5124 & 315-5246), Game Gear & Mega Drive VDP + * + * Copyright (C) 1998-2007 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _RENDER_H_ +#define _RENDER_H_ + +/* Global variables */ +extern uint16 spr_col; + +/* Function prototypes */ +extern void render_init(void); +extern void render_reset(void); +extern void render_line(int line); +extern void blank_line(int line, int offset, int width); +extern void remap_line(int line); +extern void window_clip(unsigned int data, unsigned int sw); +extern void render_bg_m0(int line); +extern void render_bg_m1(int line); +extern void render_bg_m1x(int line); +extern void render_bg_m2(int line); +extern void render_bg_m3(int line); +extern void render_bg_m3x(int line); +extern void render_bg_inv(int line); +extern void render_bg_m4(int line); +extern void render_bg_m5(int line); +extern void render_bg_m5_vs(int line); +extern void render_bg_m5_im2(int line); +extern void render_bg_m5_im2_vs(int line); +extern void render_obj_tms(int line); +extern void render_obj_m4(int line); +extern void render_obj_m5(int line); +extern void render_obj_m5_ste(int line); +extern void render_obj_m5_im2(int line); +extern void render_obj_m5_im2_ste(int line); +extern void parse_satb_tms(int line); +extern void parse_satb_m4(int line); +extern void parse_satb_m5(int line); +extern void update_bg_pattern_cache_m4(int index); +extern void update_bg_pattern_cache_m5(int index); +extern void color_update_m4(int index, unsigned int data); +extern void color_update_m5(int index, unsigned int data); + +/* Function pointers */ +extern void (*render_bg)(int line); +extern void (*render_obj)(int line); +extern void (*parse_satb)(int line); +extern void (*update_bg_pattern_cache)(int index); + +#endif /* _RENDER_H_ */ + diff --git a/genplus-gx/core/z80/osd_cpu.h b/genplus-gx/core/z80/osd_cpu.h new file mode 100644 index 0000000000..5f5e5af834 --- /dev/null +++ b/genplus-gx/core/z80/osd_cpu.h @@ -0,0 +1,47 @@ +/******************************************************************************* +* * +* Define size independent data types and operations. * +* * +* The following types must be supported by all platforms: * +* * +* UINT8 - Unsigned 8-bit Integer INT8 - Signed 8-bit integer * +* UINT16 - Unsigned 16-bit Integer INT16 - Signed 16-bit integer * +* UINT32 - Unsigned 32-bit Integer INT32 - Signed 32-bit integer * +* * +*******************************************************************************/ + +#ifndef OSD_CPU_H +#define OSD_CPU_H + +#undef TRUE +#undef FALSE +#define TRUE 1 +#define FALSE 0 + +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef signed char INT8; +typedef signed short INT16; +typedef signed int INT32; + +/****************************************************************************** + * Union of UINT8, UINT16 and UINT32 in native endianess of the target + * This is used to access bytes and words in a machine independent manner. + * The upper bytes h2 and h3 normally contain zero (16 bit CPU cores) + * thus PAIR.d can be used to pass arguments to the memory system + * which expects 'int' really. + ******************************************************************************/ + +typedef union { +#ifdef LSB_FIRST + struct { UINT8 l,h,h2,h3; } b; + struct { UINT16 l,h; } w; +#else + struct { UINT8 h3,h2,h,l; } b; + struct { UINT16 h,l; } w; +#endif + UINT32 d; +} PAIR; + +#endif /* defined OSD_CPU_H */ diff --git a/genplus-gx/core/z80/z80.c b/genplus-gx/core/z80/z80.c new file mode 100644 index 0000000000..7a1754df46 --- /dev/null +++ b/genplus-gx/core/z80/z80.c @@ -0,0 +1,3457 @@ +/***************************************************************************** + * + * z80.c + * Portable Z80 emulator V3.9 + * + * Copyright Juergen Buchmueller, all rights reserved. + * + * - This source code is released as freeware for non-commercial purposes. + * - You are free to use and redistribute this code in modified or + * unmodified form, provided you list me in the credits. + * - If you modify this source code, you must add a notice to each modified + * source file that it has been changed. If you're a nice person, you + * will clearly mark each change too. :) + * - If you wish to use this for commercial purposes, please contact me at + * pullmoll@t-online.de + * - The author of this copywritten work reserves the right to change the + * terms of its usage and license at any time, including retroactively + * - This entire notice must remain in the source code. + * + * TODO: + * - If LD A,I or LD A,R is interrupted, P/V flag gets reset, even if IFF2 + * was set before this instruction + * - Ideally, the tiny differences between Z80 types should be supported, + * currently known differences: + * - LD A,I/R P/V flag reset glitch is fixed on CMOS Z80 + * - OUT (C),0 outputs 0 on NMOS Z80, $FF on CMOS Z80 + * - SCF/CCF X/Y flags is ((flags | A) & 0x28) on SGS/SHARP/ZiLOG NMOS Z80, + * (flags & A & 0x28) on NEC NMOS Z80, other models unknown. + * However, people from the Speccy scene mention that SCF/CCF X/Y results + * are inconsistant and may be influenced by I and R registers. + * This Z80 emulator assumes a ZiLOG NMOS model. + * + * Additional changes [Eke-Eke]: + * - Removed z80_burn function (unused) + * - Discarded multi-chip support (unused) + * - Fixed cycle counting for FD and DD prefixed instructions + * - Fixed behavior of chained FD and DD prefixes (R register should be only incremented by one + * - Implemented cycle-accurate INI/IND (needed by SMS emulation) + * - Fixed Z80 reset + * - Made SZHVC_add & SZHVC_sub tables statically allocated + * Changes in 3.9: + * - Fixed cycle counts for LD IYL/IXL/IYH/IXH,n [Marshmellow] + * - Fixed X/Y flags in CCF/SCF/BIT, ZEXALL is happy now [hap] + * - Simplified DAA, renamed MEMPTR (3.8) to WZ, added TODO [hap] + * - Fixed IM2 interrupt cycles [eke] + * Changes in 3.8 [Miodrag Milanovic]: + * - Added MEMPTR register (according to informations provided + * by Vladimir Kladov + * - BIT n,(HL) now return valid values due to use of MEMPTR + * - Fixed BIT 6,(XY+o) undocumented instructions + * Changes in 3.7 [Aaron Giles]: + * - Changed NMI handling. NMIs are now latched in set_irq_state + * but are not taken there. Instead they are taken at the start of the + * execute loop. + * - Changed IRQ handling. IRQ state is set in set_irq_state but not taken + * except during the inner execute loop. + * - Removed x86 assembly hacks and obsolete timing loop catchers. + * Changes in 3.6: + * - Got rid of the code that would inexactly emulate a Z80, i.e. removed + * all the #if Z80_EXACT #else branches. + * - Removed leading underscores from local register name shortcuts as + * this violates the C99 standard. + * - Renamed the registers inside the Z80 context to lower case to avoid + * ambiguities (shortcuts would have had the same names as the fields + * of the structure). + * Changes in 3.5: + * - Implemented OTIR, INIR, etc. without look-up table for PF flag. + * [Ramsoft, Sean Young] + * Changes in 3.4: + * - Removed Z80-MSX specific code as it's not needed any more. + * - Implemented DAA without look-up table [Ramsoft, Sean Young] + * Changes in 3.3: + * - Fixed undocumented flags XF & YF in the non-asm versions of CP, + * and all the 16 bit arithmetic instructions. [Sean Young] + * Changes in 3.2: + * - Fixed undocumented flags XF & YF of RRCA, and CF and HF of + * INI/IND/OUTI/OUTD/INIR/INDR/OTIR/OTDR [Sean Young] + * Changes in 3.1: + * - removed the REPEAT_AT_ONCE execution of LDIR/CPIR etc. opcodes + * for readabilities sake and because the implementation was buggy + * (and I was not able to find the difference) + * Changes in 3.0: + * - 'finished' switch to dynamically overrideable cycle count tables + * Changes in 2.9: + * - added methods to access and override the cycle count tables + * - fixed handling and timing of multiple DD/FD prefixed opcodes + * Changes in 2.8: + * - OUTI/OUTD/OTIR/OTDR also pre-decrement the B register now. + * This was wrong because of a bug fix on the wrong side + * (astrocade sound driver). + * Changes in 2.7: + * - removed z80_vm specific code, it's not needed (and never was). + * Changes in 2.6: + * - BUSY_LOOP_HACKS needed to call change_pc() earlier, before + * checking the opcodes at the new address, because otherwise they + * might access the old (wrong or even NULL) banked memory region. + * Thanks to Sean Young for finding this nasty bug. + * Changes in 2.5: + * - Burning cycles always adjusts the ICount by a multiple of 4. + * - In REPEAT_AT_ONCE cases the R register wasn't incremented twice + * per repetition as it should have been. Those repeated opcodes + * could also underflow the ICount. + * - Simplified TIME_LOOP_HACKS for BC and added two more for DE + HL + * timing loops. I think those hacks weren't endian safe before too. + * Changes in 2.4: + * - z80_reset zaps the entire context, sets IX and IY to 0xffff(!) and + * sets the Z flag. With these changes the Tehkan World Cup driver + * _seems_ to work again. + * Changes in 2.3: + * - External termination of the execution loop calls z80_burn() and + * z80_vm_burn() to burn an amount of cycles (R adjustment) + * - Shortcuts which burn CPU cycles (BUSY_LOOP_HACKS and TIME_LOOP_HACKS) + * now also adjust the R register depending on the skipped opcodes. + * Changes in 2.2: + * - Fixed bugs in CPL, SCF and CCF instructions flag handling. + * - Changed variable EA and ARG16() function to UINT32; this + * produces slightly more efficient code. + * - The DD/FD XY CB opcodes where XY is 40-7F and Y is not 6/E + * are changed to calls to the X6/XE opcodes to reduce object size. + * They're hardly ever used so this should not yield a speed penalty. + * New in 2.0: + * - Optional more exact Z80 emulation (#define Z80_EXACT 1) according + * to a detailed description by Sean Young which can be found at: + * http://www.msxnet.org/tech/z80-documented.pdf + *****************************************************************************/ +#include "shared.h" +#include "z80.h" + +/* execute main opcodes inside a big switch statement */ +#define BIG_SWITCH 1 + +#define VERBOSE 0 + +#if VERBOSE +#define LOG(x) logerror x +#else +#define LOG(x) +#endif + +#define cpu_readop(a) z80_readmap[(a) >> 10][(a) & 0x03FF] +#define cpu_readop_arg(a) z80_readmap[(a) >> 10][(a) & 0x03FF] + +#define CF 0x01 +#define NF 0x02 +#define PF 0x04 +#define VF PF +#define XF 0x08 +#define HF 0x10 +#define YF 0x20 +#define ZF 0x40 +#define SF 0x80 + +#define INT_IRQ 0x01 +#define NMI_IRQ 0x02 + +#define PCD Z80.pc.d +#define PC Z80.pc.w.l + +#define SPD Z80.sp.d +#define SP Z80.sp.w.l + +#define AFD Z80.af.d +#define AF Z80.af.w.l +#define A Z80.af.b.h +#define F Z80.af.b.l + +#define BCD Z80.bc.d +#define BC Z80.bc.w.l +#define B Z80.bc.b.h +#define C Z80.bc.b.l + +#define DED Z80.de.d +#define DE Z80.de.w.l +#define D Z80.de.b.h +#define E Z80.de.b.l + +#define HLD Z80.hl.d +#define HL Z80.hl.w.l +#define H Z80.hl.b.h +#define L Z80.hl.b.l + +#define IXD Z80.ix.d +#define IX Z80.ix.w.l +#define HX Z80.ix.b.h +#define LX Z80.ix.b.l + +#define IYD Z80.iy.d +#define IY Z80.iy.w.l +#define HY Z80.iy.b.h +#define LY Z80.iy.b.l + +#define WZ Z80.wz.w.l +#define WZ_H Z80.wz.b.h +#define WZ_L Z80.wz.b.l + +#define I Z80.i +#define R Z80.r +#define R2 Z80.r2 +#define IM Z80.im +#define IFF1 Z80.iff1 +#define IFF2 Z80.iff2 +#define HALT Z80.halt + +Z80_Regs Z80; + +unsigned char *z80_readmap[64]; +unsigned char *z80_writemap[64]; + +void (*z80_writemem)(unsigned int address, unsigned char data); +unsigned char (*z80_readmem)(unsigned int address); +void (*z80_writeport)(unsigned int port, unsigned char data); +unsigned char (*z80_readport)(unsigned int port); + +static UINT32 EA; + +static UINT8 SZ[256]; /* zero and sign flags */ +static UINT8 SZ_BIT[256]; /* zero, sign and parity/overflow (=zero) flags for BIT opcode */ +static UINT8 SZP[256]; /* zero, sign and parity flags */ +static UINT8 SZHV_inc[256]; /* zero, sign, half carry and overflow flags INC r8 */ +static UINT8 SZHV_dec[256]; /* zero, sign, half carry and overflow flags DEC r8 */ + +static UINT8 SZHVC_add[2*256*256]; /* flags for ADD opcode */ +static UINT8 SZHVC_sub[2*256*256]; /* flags for SUB opcode */ + +static const UINT16 cc_op[0x100] = { + 4*15,10*15, 7*15, 6*15, 4*15, 4*15, 7*15, 4*15, 4*15,11*15, 7*15, 6*15, 4*15, 4*15, 7*15, 4*15, + 8*15,10*15, 7*15, 6*15, 4*15, 4*15, 7*15, 4*15,12*15,11*15, 7*15, 6*15, 4*15, 4*15, 7*15, 4*15, + 7*15,10*15,16*15, 6*15, 4*15, 4*15, 7*15, 4*15, 7*15,11*15,16*15, 6*15, 4*15, 4*15, 7*15, 4*15, + 7*15,10*15,13*15, 6*15,11*15,11*15,10*15, 4*15, 7*15,11*15,13*15, 6*15, 4*15, 4*15, 7*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, + 7*15, 7*15, 7*15, 7*15, 7*15, 7*15, 4*15, 7*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 7*15, 4*15, + 5*15,10*15,10*15,10*15,10*15,11*15, 7*15,11*15, 5*15,10*15,10*15, 0*15,10*15,17*15, 7*15,11*15, + 5*15,10*15,10*15,11*15,10*15,11*15, 7*15,11*15, 5*15, 4*15,10*15,11*15,10*15, 0*15, 7*15,11*15, + 5*15,10*15,10*15,19*15,10*15,11*15, 7*15,11*15, 5*15, 4*15,10*15, 4*15,10*15, 0*15, 7*15,11*15, + 5*15,10*15,10*15, 4*15,10*15,11*15, 7*15,11*15, 5*15, 6*15,10*15, 4*15,10*15, 0*15, 7*15,11*15}; + +static const UINT16 cc_cb[0x100] = { + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,12*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,12*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,12*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,12*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,12*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,12*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,12*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,12*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15,15*15, 8*15}; + +static const UINT16 cc_ed[0x100] = { + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, + 12*15,12*15,15*15,20*15, 8*15,14*15, 8*15, 9*15,12*15,12*15,15*15,20*15, 8*15,14*15, 8*15, 9*15, + 12*15,12*15,15*15,20*15, 8*15,14*15, 8*15, 9*15,12*15,12*15,15*15,20*15, 8*15,14*15, 8*15, 9*15, + 12*15,12*15,15*15,20*15, 8*15,14*15, 8*15,18*15,12*15,12*15,15*15,20*15, 8*15,14*15, 8*15,18*15, + 12*15,12*15,15*15,20*15, 8*15,14*15, 8*15, 8*15,12*15,12*15,15*15,20*15, 8*15,14*15, 8*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, + 16*15,16*15,16*15,16*15, 8*15, 8*15, 8*15, 8*15,16*15,16*15,16*15,16*15, 8*15, 8*15, 8*15, 8*15, + 16*15,16*15,16*15,16*15, 8*15, 8*15, 8*15, 8*15,16*15,16*15,16*15,16*15, 8*15, 8*15, 8*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15, 8*15}; + +/*static const UINT8 cc_xy[0x100] = { + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15,15*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15,15*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, + 4*15,14*15,20*15,10*15, 9*15, 9*15,11*15, 4*15, 4*15,15*15,20*15,10*15, 9*15, 9*15,11*15, 4*15, + 4*15, 4*15, 4*15, 4*15,23*15,23*15,19*15, 4*15, 4*15,15*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, + 9*15, 9*15, 9*15, 9*15, 9*15, 9*15,19*15, 9*15, 9*15, 9*15, 9*15, 9*15, 9*15, 9*15,19*15, 9*15, +19*15,19*15,19*15,19*15,19*15,19*15, 4*15,19*15, 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, 4*15, 4*15, 4*15, 4*15, 9*15, 9*15,19*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 0*15, 4*15, 4*15, 4*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, + 4*15,14*15, 4*15,23*15, 4*15,15*15, 4*15, 4*15, 4*15, 8*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, + 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15,10*15, 4*15, 4*15, 4*15, 4*15, 4*15, 4*15}; +*/ + +/* illegal combo should return 4 + cc_op[i] */ +static const UINT16 cc_xy[0x100] ={ + 8*15,14*15,11*15,10*15, 8*15, 8*15,11*15, 8*15, 8*15,15*15,11*15,10*15, 8*15, 8*15,11*15, 8*15, + 12*15,14*15,11*15,10*15, 8*15, 8*15,11*15, 8*15,16*15,15*15,11*15,10*15, 8*15, 8*15,11*15, 8*15, + 11*15,14*15,20*15,10*15, 9*15, 9*15,12*15, 8*15,11*15,15*15,20*15,10*15, 9*15, 9*15,12*15, 8*15, + 11*15,14*15,17*15,10*15,23*15,23*15,19*15, 8*15,11*15,15*15,17*15,10*15, 8*15, 8*15,11*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, + 9*15, 9*15, 9*15, 9*15, 9*15, 9*15,19*15, 9*15, 9*15, 9*15, 9*15, 9*15, 9*15, 9*15,19*15, 9*15, + 19*15,19*15,19*15,19*15,19*15,19*15, 8*15,19*15, 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, + 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, 8*15, 8*15, 8*15, 8*15, 9*15, 9*15,19*15, 8*15, + 9*15,14*15,14*15,14*15,14*15,15*15,11*15,15*15, 9*15,14*15,14*15, 0*15,14*15,21*15,11*15,15*15, + 9*15,14*15,14*15,15*15,14*15,15*15,11*15,15*15, 9*15, 8*15,14*15,15*15,14*15, 4*15,11*15,15*15, + 9*15,14*15,14*15,23*15,14*15,15*15,11*15,15*15, 9*15, 8*15,14*15, 8*15,14*15, 4*15,11*15,15*15, + 9*15,14*15,14*15, 8*15,14*15,15*15,11*15,15*15, 9*15,10*15,14*15, 8*15,14*15, 4*15,11*15,15*15}; + +static const UINT16 cc_xycb[0x100] = { + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15, + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15, + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15, + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15, + 20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15, + 20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15, + 20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15, + 20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15,20*15, + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15, + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15, + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15, + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15, + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15, + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15, + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15, + 23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15,23*15}; + +/* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */ +static const UINT16 cc_ex[0x100] = { + 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, + 5*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, /* DJNZ */ + 5*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 5*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, /* JR NZ/JR Z */ + 5*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 5*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, /* JR NC/JR C */ + 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, + 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, + 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, + 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, + 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, + 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, + 0*15, 0*15, 4*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 0*15, 4*15, 0*15, 0*15, 0*15, 0*15, 0*15, /* INI/IND (cycle-accurate I/O port reads) */ + 5*15, 5*15, 5*15, 5*15, 0*15, 0*15, 0*15, 0*15, 5*15, 5*15, 5*15, 5*15, 0*15, 0*15, 0*15, 0*15, /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */ + 6*15, 0*15, 0*15, 0*15, 7*15, 0*15, 0*15, 2*15, 6*15, 0*15, 0*15, 0*15, 7*15, 0*15, 0*15, 2*15, + 6*15, 0*15, 0*15, 0*15, 7*15, 0*15, 0*15, 2*15, 6*15, 0*15, 0*15, 0*15, 7*15, 0*15, 0*15, 2*15, + 6*15, 0*15, 0*15, 0*15, 7*15, 0*15, 0*15, 2*15, 6*15, 0*15, 0*15, 0*15, 7*15, 0*15, 0*15, 2*15, + 6*15, 0*15, 0*15, 0*15, 7*15, 0*15, 0*15, 2*15, 6*15, 0*15, 0*15, 0*15, 7*15, 0*15, 0*15, 2*15}; + +static const UINT16 *cc[6]; +#define Z80_TABLE_dd Z80_TABLE_xy +#define Z80_TABLE_fd Z80_TABLE_xy + +typedef void (*funcptr)(void); + +#define PROTOTYPES(tablename,prefix) \ + INLINE void prefix##_00(void); INLINE void prefix##_01(void); INLINE void prefix##_02(void); INLINE void prefix##_03(void); \ + INLINE void prefix##_04(void); INLINE void prefix##_05(void); INLINE void prefix##_06(void); INLINE void prefix##_07(void); \ + INLINE void prefix##_08(void); INLINE void prefix##_09(void); INLINE void prefix##_0a(void); INLINE void prefix##_0b(void); \ + INLINE void prefix##_0c(void); INLINE void prefix##_0d(void); INLINE void prefix##_0e(void); INLINE void prefix##_0f(void); \ + INLINE void prefix##_10(void); INLINE void prefix##_11(void); INLINE void prefix##_12(void); INLINE void prefix##_13(void); \ + INLINE void prefix##_14(void); INLINE void prefix##_15(void); INLINE void prefix##_16(void); INLINE void prefix##_17(void); \ + INLINE void prefix##_18(void); INLINE void prefix##_19(void); INLINE void prefix##_1a(void); INLINE void prefix##_1b(void); \ + INLINE void prefix##_1c(void); INLINE void prefix##_1d(void); INLINE void prefix##_1e(void); INLINE void prefix##_1f(void); \ + INLINE void prefix##_20(void); INLINE void prefix##_21(void); INLINE void prefix##_22(void); INLINE void prefix##_23(void); \ + INLINE void prefix##_24(void); INLINE void prefix##_25(void); INLINE void prefix##_26(void); INLINE void prefix##_27(void); \ + INLINE void prefix##_28(void); INLINE void prefix##_29(void); INLINE void prefix##_2a(void); INLINE void prefix##_2b(void); \ + INLINE void prefix##_2c(void); INLINE void prefix##_2d(void); INLINE void prefix##_2e(void); INLINE void prefix##_2f(void); \ + INLINE void prefix##_30(void); INLINE void prefix##_31(void); INLINE void prefix##_32(void); INLINE void prefix##_33(void); \ + INLINE void prefix##_34(void); INLINE void prefix##_35(void); INLINE void prefix##_36(void); INLINE void prefix##_37(void); \ + INLINE void prefix##_38(void); INLINE void prefix##_39(void); INLINE void prefix##_3a(void); INLINE void prefix##_3b(void); \ + INLINE void prefix##_3c(void); INLINE void prefix##_3d(void); INLINE void prefix##_3e(void); INLINE void prefix##_3f(void); \ + INLINE void prefix##_40(void); INLINE void prefix##_41(void); INLINE void prefix##_42(void); INLINE void prefix##_43(void); \ + INLINE void prefix##_44(void); INLINE void prefix##_45(void); INLINE void prefix##_46(void); INLINE void prefix##_47(void); \ + INLINE void prefix##_48(void); INLINE void prefix##_49(void); INLINE void prefix##_4a(void); INLINE void prefix##_4b(void); \ + INLINE void prefix##_4c(void); INLINE void prefix##_4d(void); INLINE void prefix##_4e(void); INLINE void prefix##_4f(void); \ + INLINE void prefix##_50(void); INLINE void prefix##_51(void); INLINE void prefix##_52(void); INLINE void prefix##_53(void); \ + INLINE void prefix##_54(void); INLINE void prefix##_55(void); INLINE void prefix##_56(void); INLINE void prefix##_57(void); \ + INLINE void prefix##_58(void); INLINE void prefix##_59(void); INLINE void prefix##_5a(void); INLINE void prefix##_5b(void); \ + INLINE void prefix##_5c(void); INLINE void prefix##_5d(void); INLINE void prefix##_5e(void); INLINE void prefix##_5f(void); \ + INLINE void prefix##_60(void); INLINE void prefix##_61(void); INLINE void prefix##_62(void); INLINE void prefix##_63(void); \ + INLINE void prefix##_64(void); INLINE void prefix##_65(void); INLINE void prefix##_66(void); INLINE void prefix##_67(void); \ + INLINE void prefix##_68(void); INLINE void prefix##_69(void); INLINE void prefix##_6a(void); INLINE void prefix##_6b(void); \ + INLINE void prefix##_6c(void); INLINE void prefix##_6d(void); INLINE void prefix##_6e(void); INLINE void prefix##_6f(void); \ + INLINE void prefix##_70(void); INLINE void prefix##_71(void); INLINE void prefix##_72(void); INLINE void prefix##_73(void); \ + INLINE void prefix##_74(void); INLINE void prefix##_75(void); INLINE void prefix##_76(void); INLINE void prefix##_77(void); \ + INLINE void prefix##_78(void); INLINE void prefix##_79(void); INLINE void prefix##_7a(void); INLINE void prefix##_7b(void); \ + INLINE void prefix##_7c(void); INLINE void prefix##_7d(void); INLINE void prefix##_7e(void); INLINE void prefix##_7f(void); \ + INLINE void prefix##_80(void); INLINE void prefix##_81(void); INLINE void prefix##_82(void); INLINE void prefix##_83(void); \ + INLINE void prefix##_84(void); INLINE void prefix##_85(void); INLINE void prefix##_86(void); INLINE void prefix##_87(void); \ + INLINE void prefix##_88(void); INLINE void prefix##_89(void); INLINE void prefix##_8a(void); INLINE void prefix##_8b(void); \ + INLINE void prefix##_8c(void); INLINE void prefix##_8d(void); INLINE void prefix##_8e(void); INLINE void prefix##_8f(void); \ + INLINE void prefix##_90(void); INLINE void prefix##_91(void); INLINE void prefix##_92(void); INLINE void prefix##_93(void); \ + INLINE void prefix##_94(void); INLINE void prefix##_95(void); INLINE void prefix##_96(void); INLINE void prefix##_97(void); \ + INLINE void prefix##_98(void); INLINE void prefix##_99(void); INLINE void prefix##_9a(void); INLINE void prefix##_9b(void); \ + INLINE void prefix##_9c(void); INLINE void prefix##_9d(void); INLINE void prefix##_9e(void); INLINE void prefix##_9f(void); \ + INLINE void prefix##_a0(void); INLINE void prefix##_a1(void); INLINE void prefix##_a2(void); INLINE void prefix##_a3(void); \ + INLINE void prefix##_a4(void); INLINE void prefix##_a5(void); INLINE void prefix##_a6(void); INLINE void prefix##_a7(void); \ + INLINE void prefix##_a8(void); INLINE void prefix##_a9(void); INLINE void prefix##_aa(void); INLINE void prefix##_ab(void); \ + INLINE void prefix##_ac(void); INLINE void prefix##_ad(void); INLINE void prefix##_ae(void); INLINE void prefix##_af(void); \ + INLINE void prefix##_b0(void); INLINE void prefix##_b1(void); INLINE void prefix##_b2(void); INLINE void prefix##_b3(void); \ + INLINE void prefix##_b4(void); INLINE void prefix##_b5(void); INLINE void prefix##_b6(void); INLINE void prefix##_b7(void); \ + INLINE void prefix##_b8(void); INLINE void prefix##_b9(void); INLINE void prefix##_ba(void); INLINE void prefix##_bb(void); \ + INLINE void prefix##_bc(void); INLINE void prefix##_bd(void); INLINE void prefix##_be(void); INLINE void prefix##_bf(void); \ + INLINE void prefix##_c0(void); INLINE void prefix##_c1(void); INLINE void prefix##_c2(void); INLINE void prefix##_c3(void); \ + INLINE void prefix##_c4(void); INLINE void prefix##_c5(void); INLINE void prefix##_c6(void); INLINE void prefix##_c7(void); \ + INLINE void prefix##_c8(void); INLINE void prefix##_c9(void); INLINE void prefix##_ca(void); INLINE void prefix##_cb(void); \ + INLINE void prefix##_cc(void); INLINE void prefix##_cd(void); INLINE void prefix##_ce(void); INLINE void prefix##_cf(void); \ + INLINE void prefix##_d0(void); INLINE void prefix##_d1(void); INLINE void prefix##_d2(void); INLINE void prefix##_d3(void); \ + INLINE void prefix##_d4(void); INLINE void prefix##_d5(void); INLINE void prefix##_d6(void); INLINE void prefix##_d7(void); \ + INLINE void prefix##_d8(void); INLINE void prefix##_d9(void); INLINE void prefix##_da(void); INLINE void prefix##_db(void); \ + INLINE void prefix##_dc(void); INLINE void prefix##_dd(void); INLINE void prefix##_de(void); INLINE void prefix##_df(void); \ + INLINE void prefix##_e0(void); INLINE void prefix##_e1(void); INLINE void prefix##_e2(void); INLINE void prefix##_e3(void); \ + INLINE void prefix##_e4(void); INLINE void prefix##_e5(void); INLINE void prefix##_e6(void); INLINE void prefix##_e7(void); \ + INLINE void prefix##_e8(void); INLINE void prefix##_e9(void); INLINE void prefix##_ea(void); INLINE void prefix##_eb(void); \ + INLINE void prefix##_ec(void); INLINE void prefix##_ed(void); INLINE void prefix##_ee(void); INLINE void prefix##_ef(void); \ + INLINE void prefix##_f0(void); INLINE void prefix##_f1(void); INLINE void prefix##_f2(void); INLINE void prefix##_f3(void); \ + INLINE void prefix##_f4(void); INLINE void prefix##_f5(void); INLINE void prefix##_f6(void); INLINE void prefix##_f7(void); \ + INLINE void prefix##_f8(void); INLINE void prefix##_f9(void); INLINE void prefix##_fa(void); INLINE void prefix##_fb(void); \ + INLINE void prefix##_fc(void); INLINE void prefix##_fd(void); INLINE void prefix##_fe(void); INLINE void prefix##_ff(void); \ +static const funcptr tablename[0x100] = { \ + prefix##_00,prefix##_01,prefix##_02,prefix##_03,prefix##_04,prefix##_05,prefix##_06,prefix##_07, \ + prefix##_08,prefix##_09,prefix##_0a,prefix##_0b,prefix##_0c,prefix##_0d,prefix##_0e,prefix##_0f, \ + prefix##_10,prefix##_11,prefix##_12,prefix##_13,prefix##_14,prefix##_15,prefix##_16,prefix##_17, \ + prefix##_18,prefix##_19,prefix##_1a,prefix##_1b,prefix##_1c,prefix##_1d,prefix##_1e,prefix##_1f, \ + prefix##_20,prefix##_21,prefix##_22,prefix##_23,prefix##_24,prefix##_25,prefix##_26,prefix##_27, \ + prefix##_28,prefix##_29,prefix##_2a,prefix##_2b,prefix##_2c,prefix##_2d,prefix##_2e,prefix##_2f, \ + prefix##_30,prefix##_31,prefix##_32,prefix##_33,prefix##_34,prefix##_35,prefix##_36,prefix##_37, \ + prefix##_38,prefix##_39,prefix##_3a,prefix##_3b,prefix##_3c,prefix##_3d,prefix##_3e,prefix##_3f, \ + prefix##_40,prefix##_41,prefix##_42,prefix##_43,prefix##_44,prefix##_45,prefix##_46,prefix##_47, \ + prefix##_48,prefix##_49,prefix##_4a,prefix##_4b,prefix##_4c,prefix##_4d,prefix##_4e,prefix##_4f, \ + prefix##_50,prefix##_51,prefix##_52,prefix##_53,prefix##_54,prefix##_55,prefix##_56,prefix##_57, \ + prefix##_58,prefix##_59,prefix##_5a,prefix##_5b,prefix##_5c,prefix##_5d,prefix##_5e,prefix##_5f, \ + prefix##_60,prefix##_61,prefix##_62,prefix##_63,prefix##_64,prefix##_65,prefix##_66,prefix##_67, \ + prefix##_68,prefix##_69,prefix##_6a,prefix##_6b,prefix##_6c,prefix##_6d,prefix##_6e,prefix##_6f, \ + prefix##_70,prefix##_71,prefix##_72,prefix##_73,prefix##_74,prefix##_75,prefix##_76,prefix##_77, \ + prefix##_78,prefix##_79,prefix##_7a,prefix##_7b,prefix##_7c,prefix##_7d,prefix##_7e,prefix##_7f, \ + prefix##_80,prefix##_81,prefix##_82,prefix##_83,prefix##_84,prefix##_85,prefix##_86,prefix##_87, \ + prefix##_88,prefix##_89,prefix##_8a,prefix##_8b,prefix##_8c,prefix##_8d,prefix##_8e,prefix##_8f, \ + prefix##_90,prefix##_91,prefix##_92,prefix##_93,prefix##_94,prefix##_95,prefix##_96,prefix##_97, \ + prefix##_98,prefix##_99,prefix##_9a,prefix##_9b,prefix##_9c,prefix##_9d,prefix##_9e,prefix##_9f, \ + prefix##_a0,prefix##_a1,prefix##_a2,prefix##_a3,prefix##_a4,prefix##_a5,prefix##_a6,prefix##_a7, \ + prefix##_a8,prefix##_a9,prefix##_aa,prefix##_ab,prefix##_ac,prefix##_ad,prefix##_ae,prefix##_af, \ + prefix##_b0,prefix##_b1,prefix##_b2,prefix##_b3,prefix##_b4,prefix##_b5,prefix##_b6,prefix##_b7, \ + prefix##_b8,prefix##_b9,prefix##_ba,prefix##_bb,prefix##_bc,prefix##_bd,prefix##_be,prefix##_bf, \ + prefix##_c0,prefix##_c1,prefix##_c2,prefix##_c3,prefix##_c4,prefix##_c5,prefix##_c6,prefix##_c7, \ + prefix##_c8,prefix##_c9,prefix##_ca,prefix##_cb,prefix##_cc,prefix##_cd,prefix##_ce,prefix##_cf, \ + prefix##_d0,prefix##_d1,prefix##_d2,prefix##_d3,prefix##_d4,prefix##_d5,prefix##_d6,prefix##_d7, \ + prefix##_d8,prefix##_d9,prefix##_da,prefix##_db,prefix##_dc,prefix##_dd,prefix##_de,prefix##_df, \ + prefix##_e0,prefix##_e1,prefix##_e2,prefix##_e3,prefix##_e4,prefix##_e5,prefix##_e6,prefix##_e7, \ + prefix##_e8,prefix##_e9,prefix##_ea,prefix##_eb,prefix##_ec,prefix##_ed,prefix##_ee,prefix##_ef, \ + prefix##_f0,prefix##_f1,prefix##_f2,prefix##_f3,prefix##_f4,prefix##_f5,prefix##_f6,prefix##_f7, \ + prefix##_f8,prefix##_f9,prefix##_fa,prefix##_fb,prefix##_fc,prefix##_fd,prefix##_fe,prefix##_ff \ +} + +PROTOTYPES(Z80op,op); +PROTOTYPES(Z80cb,cb); +PROTOTYPES(Z80dd,dd); +PROTOTYPES(Z80ed,ed); +PROTOTYPES(Z80fd,fd); +PROTOTYPES(Z80xycb,xycb); + +/****************************************************************************/ +/* Burn an odd amount of cycles, that is instructions taking something */ +/* different from 4 T-states per opcode (and R increment) */ +/****************************************************************************/ +INLINE void BURNODD(int cycles, int opcodes, int cyclesum) +{ + if( cycles > 0 ) + { + R += (cycles / cyclesum) * opcodes; + Z80.cycles += (cycles / cyclesum) * cyclesum * 15; + } +} + +/*************************************************************** + * define an opcode function + ***************************************************************/ +#define OP(prefix,opcode) INLINE void prefix##_##opcode(void) + +/*************************************************************** + * adjust cycle count by n T-states + ***************************************************************/ +#define CC(prefix,opcode) Z80.cycles += cc[Z80_TABLE_##prefix][opcode] + +/*************************************************************** + * execute an opcode + ***************************************************************/ +#define EXEC(prefix,opcode) \ +{ \ + unsigned op = opcode; \ + CC(prefix,op); \ + (*Z80##prefix[op])(); \ +} + +#if BIG_SWITCH +#define EXEC_INLINE(prefix,opcode) \ +{ \ + unsigned op = opcode; \ + CC(prefix,op); \ + switch(op) \ + { \ + case 0x00:prefix##_##00();break; case 0x01:prefix##_##01();break; case 0x02:prefix##_##02();break; case 0x03:prefix##_##03();break; \ + case 0x04:prefix##_##04();break; case 0x05:prefix##_##05();break; case 0x06:prefix##_##06();break; case 0x07:prefix##_##07();break; \ + case 0x08:prefix##_##08();break; case 0x09:prefix##_##09();break; case 0x0a:prefix##_##0a();break; case 0x0b:prefix##_##0b();break; \ + case 0x0c:prefix##_##0c();break; case 0x0d:prefix##_##0d();break; case 0x0e:prefix##_##0e();break; case 0x0f:prefix##_##0f();break; \ + case 0x10:prefix##_##10();break; case 0x11:prefix##_##11();break; case 0x12:prefix##_##12();break; case 0x13:prefix##_##13();break; \ + case 0x14:prefix##_##14();break; case 0x15:prefix##_##15();break; case 0x16:prefix##_##16();break; case 0x17:prefix##_##17();break; \ + case 0x18:prefix##_##18();break; case 0x19:prefix##_##19();break; case 0x1a:prefix##_##1a();break; case 0x1b:prefix##_##1b();break; \ + case 0x1c:prefix##_##1c();break; case 0x1d:prefix##_##1d();break; case 0x1e:prefix##_##1e();break; case 0x1f:prefix##_##1f();break; \ + case 0x20:prefix##_##20();break; case 0x21:prefix##_##21();break; case 0x22:prefix##_##22();break; case 0x23:prefix##_##23();break; \ + case 0x24:prefix##_##24();break; case 0x25:prefix##_##25();break; case 0x26:prefix##_##26();break; case 0x27:prefix##_##27();break; \ + case 0x28:prefix##_##28();break; case 0x29:prefix##_##29();break; case 0x2a:prefix##_##2a();break; case 0x2b:prefix##_##2b();break; \ + case 0x2c:prefix##_##2c();break; case 0x2d:prefix##_##2d();break; case 0x2e:prefix##_##2e();break; case 0x2f:prefix##_##2f();break; \ + case 0x30:prefix##_##30();break; case 0x31:prefix##_##31();break; case 0x32:prefix##_##32();break; case 0x33:prefix##_##33();break; \ + case 0x34:prefix##_##34();break; case 0x35:prefix##_##35();break; case 0x36:prefix##_##36();break; case 0x37:prefix##_##37();break; \ + case 0x38:prefix##_##38();break; case 0x39:prefix##_##39();break; case 0x3a:prefix##_##3a();break; case 0x3b:prefix##_##3b();break; \ + case 0x3c:prefix##_##3c();break; case 0x3d:prefix##_##3d();break; case 0x3e:prefix##_##3e();break; case 0x3f:prefix##_##3f();break; \ + case 0x40:prefix##_##40();break; case 0x41:prefix##_##41();break; case 0x42:prefix##_##42();break; case 0x43:prefix##_##43();break; \ + case 0x44:prefix##_##44();break; case 0x45:prefix##_##45();break; case 0x46:prefix##_##46();break; case 0x47:prefix##_##47();break; \ + case 0x48:prefix##_##48();break; case 0x49:prefix##_##49();break; case 0x4a:prefix##_##4a();break; case 0x4b:prefix##_##4b();break; \ + case 0x4c:prefix##_##4c();break; case 0x4d:prefix##_##4d();break; case 0x4e:prefix##_##4e();break; case 0x4f:prefix##_##4f();break; \ + case 0x50:prefix##_##50();break; case 0x51:prefix##_##51();break; case 0x52:prefix##_##52();break; case 0x53:prefix##_##53();break; \ + case 0x54:prefix##_##54();break; case 0x55:prefix##_##55();break; case 0x56:prefix##_##56();break; case 0x57:prefix##_##57();break; \ + case 0x58:prefix##_##58();break; case 0x59:prefix##_##59();break; case 0x5a:prefix##_##5a();break; case 0x5b:prefix##_##5b();break; \ + case 0x5c:prefix##_##5c();break; case 0x5d:prefix##_##5d();break; case 0x5e:prefix##_##5e();break; case 0x5f:prefix##_##5f();break; \ + case 0x60:prefix##_##60();break; case 0x61:prefix##_##61();break; case 0x62:prefix##_##62();break; case 0x63:prefix##_##63();break; \ + case 0x64:prefix##_##64();break; case 0x65:prefix##_##65();break; case 0x66:prefix##_##66();break; case 0x67:prefix##_##67();break; \ + case 0x68:prefix##_##68();break; case 0x69:prefix##_##69();break; case 0x6a:prefix##_##6a();break; case 0x6b:prefix##_##6b();break; \ + case 0x6c:prefix##_##6c();break; case 0x6d:prefix##_##6d();break; case 0x6e:prefix##_##6e();break; case 0x6f:prefix##_##6f();break; \ + case 0x70:prefix##_##70();break; case 0x71:prefix##_##71();break; case 0x72:prefix##_##72();break; case 0x73:prefix##_##73();break; \ + case 0x74:prefix##_##74();break; case 0x75:prefix##_##75();break; case 0x76:prefix##_##76();break; case 0x77:prefix##_##77();break; \ + case 0x78:prefix##_##78();break; case 0x79:prefix##_##79();break; case 0x7a:prefix##_##7a();break; case 0x7b:prefix##_##7b();break; \ + case 0x7c:prefix##_##7c();break; case 0x7d:prefix##_##7d();break; case 0x7e:prefix##_##7e();break; case 0x7f:prefix##_##7f();break; \ + case 0x80:prefix##_##80();break; case 0x81:prefix##_##81();break; case 0x82:prefix##_##82();break; case 0x83:prefix##_##83();break; \ + case 0x84:prefix##_##84();break; case 0x85:prefix##_##85();break; case 0x86:prefix##_##86();break; case 0x87:prefix##_##87();break; \ + case 0x88:prefix##_##88();break; case 0x89:prefix##_##89();break; case 0x8a:prefix##_##8a();break; case 0x8b:prefix##_##8b();break; \ + case 0x8c:prefix##_##8c();break; case 0x8d:prefix##_##8d();break; case 0x8e:prefix##_##8e();break; case 0x8f:prefix##_##8f();break; \ + case 0x90:prefix##_##90();break; case 0x91:prefix##_##91();break; case 0x92:prefix##_##92();break; case 0x93:prefix##_##93();break; \ + case 0x94:prefix##_##94();break; case 0x95:prefix##_##95();break; case 0x96:prefix##_##96();break; case 0x97:prefix##_##97();break; \ + case 0x98:prefix##_##98();break; case 0x99:prefix##_##99();break; case 0x9a:prefix##_##9a();break; case 0x9b:prefix##_##9b();break; \ + case 0x9c:prefix##_##9c();break; case 0x9d:prefix##_##9d();break; case 0x9e:prefix##_##9e();break; case 0x9f:prefix##_##9f();break; \ + case 0xa0:prefix##_##a0();break; case 0xa1:prefix##_##a1();break; case 0xa2:prefix##_##a2();break; case 0xa3:prefix##_##a3();break; \ + case 0xa4:prefix##_##a4();break; case 0xa5:prefix##_##a5();break; case 0xa6:prefix##_##a6();break; case 0xa7:prefix##_##a7();break; \ + case 0xa8:prefix##_##a8();break; case 0xa9:prefix##_##a9();break; case 0xaa:prefix##_##aa();break; case 0xab:prefix##_##ab();break; \ + case 0xac:prefix##_##ac();break; case 0xad:prefix##_##ad();break; case 0xae:prefix##_##ae();break; case 0xaf:prefix##_##af();break; \ + case 0xb0:prefix##_##b0();break; case 0xb1:prefix##_##b1();break; case 0xb2:prefix##_##b2();break; case 0xb3:prefix##_##b3();break; \ + case 0xb4:prefix##_##b4();break; case 0xb5:prefix##_##b5();break; case 0xb6:prefix##_##b6();break; case 0xb7:prefix##_##b7();break; \ + case 0xb8:prefix##_##b8();break; case 0xb9:prefix##_##b9();break; case 0xba:prefix##_##ba();break; case 0xbb:prefix##_##bb();break; \ + case 0xbc:prefix##_##bc();break; case 0xbd:prefix##_##bd();break; case 0xbe:prefix##_##be();break; case 0xbf:prefix##_##bf();break; \ + case 0xc0:prefix##_##c0();break; case 0xc1:prefix##_##c1();break; case 0xc2:prefix##_##c2();break; case 0xc3:prefix##_##c3();break; \ + case 0xc4:prefix##_##c4();break; case 0xc5:prefix##_##c5();break; case 0xc6:prefix##_##c6();break; case 0xc7:prefix##_##c7();break; \ + case 0xc8:prefix##_##c8();break; case 0xc9:prefix##_##c9();break; case 0xca:prefix##_##ca();break; case 0xcb:prefix##_##cb();break; \ + case 0xcc:prefix##_##cc();break; case 0xcd:prefix##_##cd();break; case 0xce:prefix##_##ce();break; case 0xcf:prefix##_##cf();break; \ + case 0xd0:prefix##_##d0();break; case 0xd1:prefix##_##d1();break; case 0xd2:prefix##_##d2();break; case 0xd3:prefix##_##d3();break; \ + case 0xd4:prefix##_##d4();break; case 0xd5:prefix##_##d5();break; case 0xd6:prefix##_##d6();break; case 0xd7:prefix##_##d7();break; \ + case 0xd8:prefix##_##d8();break; case 0xd9:prefix##_##d9();break; case 0xda:prefix##_##da();break; case 0xdb:prefix##_##db();break; \ + case 0xdc:prefix##_##dc();break; case 0xdd:prefix##_##dd();break; case 0xde:prefix##_##de();break; case 0xdf:prefix##_##df();break; \ + case 0xe0:prefix##_##e0();break; case 0xe1:prefix##_##e1();break; case 0xe2:prefix##_##e2();break; case 0xe3:prefix##_##e3();break; \ + case 0xe4:prefix##_##e4();break; case 0xe5:prefix##_##e5();break; case 0xe6:prefix##_##e6();break; case 0xe7:prefix##_##e7();break; \ + case 0xe8:prefix##_##e8();break; case 0xe9:prefix##_##e9();break; case 0xea:prefix##_##ea();break; case 0xeb:prefix##_##eb();break; \ + case 0xec:prefix##_##ec();break; case 0xed:prefix##_##ed();break; case 0xee:prefix##_##ee();break; case 0xef:prefix##_##ef();break; \ + case 0xf0:prefix##_##f0();break; case 0xf1:prefix##_##f1();break; case 0xf2:prefix##_##f2();break; case 0xf3:prefix##_##f3();break; \ + case 0xf4:prefix##_##f4();break; case 0xf5:prefix##_##f5();break; case 0xf6:prefix##_##f6();break; case 0xf7:prefix##_##f7();break; \ + case 0xf8:prefix##_##f8();break; case 0xf9:prefix##_##f9();break; case 0xfa:prefix##_##fa();break; case 0xfb:prefix##_##fb();break; \ + case 0xfc:prefix##_##fc();break; case 0xfd:prefix##_##fd();break; case 0xfe:prefix##_##fe();break; case 0xff:prefix##_##ff();break; \ + } \ +} +#else +#define EXEC_INLINE EXEC +#endif + + +/*************************************************************** + * Enter HALT state; write 1 to fake port on first execution + ***************************************************************/ +#define ENTER_HALT { \ + PC--; \ + HALT = 1; \ +} + +/*************************************************************** + * Leave HALT state; write 0 to fake port + ***************************************************************/ +#define LEAVE_HALT { \ + if( HALT ) \ + { \ + HALT = 0; \ + PC++; \ + } \ +} + +/*************************************************************** + * Input a byte from given I/O port + ***************************************************************/ +#define IN(port) z80_readport(port) + +/*************************************************************** + * Output a byte to given I/O port + ***************************************************************/ +#define OUT(port,value) z80_writeport(port,value) + +/*************************************************************** + * Read a byte from given memory location + ***************************************************************/ +#define RM(addr) z80_readmem(addr) + +/*************************************************************** + * Write a byte to given memory location + ***************************************************************/ +#define WM(addr,value) z80_writemem(addr,value) + +/*************************************************************** + * Read a word from given memory location + ***************************************************************/ +INLINE void RM16( UINT32 addr, PAIR *r ) +{ + r->b.l = RM(addr); + r->b.h = RM((addr+1)&0xffff); +} + +/*************************************************************** + * Write a word to given memory location + ***************************************************************/ +INLINE void WM16( UINT32 addr, PAIR *r ) +{ + WM(addr,r->b.l); + WM((addr+1)&0xffff,r->b.h); +} + +/*************************************************************** + * ROP() is identical to RM() except it is used for + * reading opcodes. In case of system with memory mapped I/O, + * this function can be used to greatly speed up emulation + ***************************************************************/ +INLINE UINT8 ROP(void) +{ + unsigned pc = PCD; + PC++; + return cpu_readop(pc); +} + +/**************************************************************** + * ARG() is identical to ROP() except it is used + * for reading opcode arguments. This difference can be used to + * support systems that use different encoding mechanisms for + * opcodes and opcode arguments + ***************************************************************/ +INLINE UINT8 ARG(void) +{ + unsigned pc = PCD; + PC++; + return cpu_readop_arg(pc); +} + +INLINE UINT32 ARG16(void) +{ + unsigned pc = PCD; + PC += 2; + return cpu_readop_arg(pc) | (cpu_readop_arg((pc+1)&0xffff) << 8); +} + +/*************************************************************** + * Calculate the effective address EA of an opcode using + * IX+offset resp. IY+offset addressing. + ***************************************************************/ +#define EAX do { EA = (UINT32)(UINT16)(IX + (INT8)ARG()); WZ = EA; } while (0) +#define EAY do { EA = (UINT32)(UINT16)(IY + (INT8)ARG()); WZ = EA; } while (0) + +/*************************************************************** + * POP + ***************************************************************/ +#define POP(DR) do { RM16( SPD, &Z80.DR ); SP += 2; } while (0) + +/*************************************************************** + * PUSH + ***************************************************************/ +#define PUSH(SR) do { SP -= 2; WM16( SPD, &Z80.SR ); } while (0) + +/*************************************************************** + * JP + ***************************************************************/ +#define JP { \ + PCD = ARG16(); \ + WZ = PCD; \ +} + +/*************************************************************** + * JP_COND + ***************************************************************/ +#define JP_COND(cond) { \ + if (cond) \ + { \ + PCD = ARG16(); \ + WZ = PCD; \ + } \ + else \ + { \ + WZ = ARG16(); /* implicit do PC += 2 */ \ + } \ +} + +/*************************************************************** + * JR + ***************************************************************/ +#define JR() { \ + INT8 arg = (INT8)ARG(); /* ARG() also increments PC */ \ + PC += arg; /* so don't do PC += ARG() */ \ + WZ = PC; \ +} + +/*************************************************************** + * JR_COND + ***************************************************************/ +#define JR_COND(cond, opcode) { \ + if (cond) \ + { \ + JR(); \ + CC(ex, opcode); \ + } \ + else PC++; \ +} + +/*************************************************************** + * CALL + ***************************************************************/ +#define CALL() { \ + EA = ARG16(); \ + WZ = EA; \ + PUSH(pc); \ + PCD = EA; \ +} + +/*************************************************************** + * CALL_COND + ***************************************************************/ +#define CALL_COND(cond, opcode) { \ + if (cond) \ + { \ + EA = ARG16(); \ + WZ = EA; \ + PUSH(pc); \ + PCD = EA; \ + CC(ex, opcode); \ + } \ + else \ + { \ + WZ = ARG16(); /* implicit call PC+=2; */ \ + } \ +} + +/*************************************************************** + * RET_COND + ***************************************************************/ +#define RET_COND(cond, opcode) do { \ + if (cond) \ + { \ + POP(pc); \ + WZ = PC; \ + CC(ex, opcode); \ + } \ +} while (0) + +/*************************************************************** + * RETN + ***************************************************************/ +#define RETN do { \ + LOG(("Z80 #%d RETN IFF1:%d IFF2:%d\n", cpu_getactivecpu(), IFF1, IFF2)); \ + POP( pc ); \ + WZ = PC; \ + IFF1 = IFF2; \ +} while (0) + +/*************************************************************** + * RETI + ***************************************************************/ +#define RETI { \ + POP( pc ); \ + WZ = PC; \ +/* according to http://www.msxnet.org/tech/z80-documented.pdf */ \ + IFF1 = IFF2; \ +} + +/*************************************************************** + * LD R,A + ***************************************************************/ +#define LD_R_A { \ + R = A; \ + R2 = A & 0x80; /* keep bit 7 of R */ \ +} + +/*************************************************************** + * LD A,R + ***************************************************************/ +#define LD_A_R { \ + A = (R & 0x7f) | R2; \ + F = (F & CF) | SZ[A] | ( IFF2 << 2 ); \ +} + +/*************************************************************** + * LD I,A + ***************************************************************/ +#define LD_I_A { \ + I = A; \ +} + +/*************************************************************** + * LD A,I + ***************************************************************/ +#define LD_A_I { \ + A = I; \ + F = (F & CF) | SZ[A] | ( IFF2 << 2 ); \ +} + +/*************************************************************** + * RST + ***************************************************************/ +#define RST(addr) \ + PUSH( pc ); \ + PCD = addr; \ + WZ = PC; \ + +/*************************************************************** + * INC r8 + ***************************************************************/ +INLINE UINT8 INC(UINT8 value) +{ + UINT8 res = value + 1; + F = (F & CF) | SZHV_inc[res]; + return (UINT8)res; +} + +/*************************************************************** + * DEC r8 + ***************************************************************/ +INLINE UINT8 DEC(UINT8 value) +{ + UINT8 res = value - 1; + F = (F & CF) | SZHV_dec[res]; + return res; +} + +/*************************************************************** + * RLCA + ***************************************************************/ +#define RLCA \ + A = (A << 1) | (A >> 7); \ + F = (F & (SF | ZF | PF)) | (A & (YF | XF | CF)) + +/*************************************************************** + * RRCA + ***************************************************************/ +#define RRCA \ + F = (F & (SF | ZF | PF)) | (A & CF); \ + A = (A >> 1) | (A << 7); \ + F |= (A & (YF | XF) ) + +/*************************************************************** + * RLA + ***************************************************************/ +#define RLA { \ + UINT8 res = (A << 1) | (F & CF); \ + UINT8 c = (A & 0x80) ? CF : 0; \ + F = (F & (SF | ZF | PF)) | c | (res & (YF | XF)); \ + A = res; \ +} + +/*************************************************************** + * RRA + ***************************************************************/ +#define RRA { \ + UINT8 res = (A >> 1) | (F << 7); \ + UINT8 c = (A & 0x01) ? CF : 0; \ + F = (F & (SF | ZF | PF)) | c | (res & (YF | XF)); \ + A = res; \ +} + +/*************************************************************** + * RRD + ***************************************************************/ +#define RRD { \ + UINT8 n = RM(HL); \ + WZ = HL+1; \ + WM( HL, (n >> 4) | (A << 4) ); \ + A = (A & 0xf0) | (n & 0x0f); \ + F = (F & CF) | SZP[A]; \ +} + +/*************************************************************** + * RLD + ***************************************************************/ +#define RLD { \ + UINT8 n = RM(HL); \ + WZ = HL+1; \ + WM( HL, (n << 4) | (A & 0x0f) ); \ + A = (A & 0xf0) | (n >> 4); \ + F = (F & CF) | SZP[A]; \ +} + +/*************************************************************** + * ADD A,n + ***************************************************************/ +#define ADD(value) \ +{ \ + UINT32 ah = AFD & 0xff00; \ + UINT32 res = (UINT8)((ah >> 8) + value); \ + F = SZHVC_add[ah | res]; \ + A = res; \ +} + +/*************************************************************** + * ADC A,n + ***************************************************************/ +#define ADC(value) \ +{ \ + UINT32 ah = AFD & 0xff00, c = AFD & 1; \ + UINT32 res = (UINT8)((ah >> 8) + value + c); \ + F = SZHVC_add[(c << 16) | ah | res]; \ + A = res; \ +} + +/*************************************************************** + * SUB n + ***************************************************************/ +#define SUB(value) \ +{ \ + UINT32 ah = AFD & 0xff00; \ + UINT32 res = (UINT8)((ah >> 8) - value); \ + F = SZHVC_sub[ah | res]; \ + A = res; \ +} + +/*************************************************************** + * SBC A,n + ***************************************************************/ +#define SBC(value) \ +{ \ + UINT32 ah = AFD & 0xff00, c = AFD & 1; \ + UINT32 res = (UINT8)((ah >> 8) - value - c); \ + F = SZHVC_sub[(c<<16) | ah | res]; \ + A = res; \ +} + +/*************************************************************** + * NEG + ***************************************************************/ +#define NEG { \ + UINT8 value = A; \ + A = 0; \ + SUB(value); \ +} + +/*************************************************************** + * DAA + ***************************************************************/ +#define DAA { \ + UINT8 a = A; \ + if (F & NF) { \ + if ((F&HF) | ((A&0xf)>9)) a-=6; \ + if ((F&CF) | (A>0x99)) a-=0x60; \ + } \ + else { \ + if ((F&HF) | ((A&0xf)>9)) a+=6; \ + if ((F&CF) | (A>0x99)) a+=0x60; \ + } \ + \ + F = (F&(CF|NF)) | (A>0x99) | ((A^a)&HF) | SZP[a]; \ + A = a; \ +} + +/*************************************************************** + * AND n + ***************************************************************/ +#define AND(value) \ + A &= value; \ + F = SZP[A] | HF + +/*************************************************************** + * OR n + ***************************************************************/ +#define OR(value) \ + A |= value; \ + F = SZP[A] + +/*************************************************************** + * XOR n + ***************************************************************/ +#define XOR(value) \ + A ^= value; \ + F = SZP[A] + +/*************************************************************** + * CP n + ***************************************************************/ +#define CP(value) \ +{ \ + unsigned val = value; \ + UINT32 ah = AFD & 0xff00; \ + UINT32 res = (UINT8)((ah >> 8) - val); \ + F = (SZHVC_sub[ah | res] & ~(YF | XF)) | (val & (YF | XF)); \ +} + +/*************************************************************** + * EX AF,AF' + ***************************************************************/ +#define EX_AF \ +{ \ + PAIR tmp; \ + tmp = Z80.af; Z80.af = Z80.af2; Z80.af2 = tmp; \ +} + +/*************************************************************** + * EX DE,HL + ***************************************************************/ +#define EX_DE_HL \ +{ \ + PAIR tmp; \ + tmp = Z80.de; Z80.de = Z80.hl; Z80.hl = tmp; \ +} + +/*************************************************************** + * EXX + ***************************************************************/ +#define EXX \ +{ \ + PAIR tmp; \ + tmp = Z80.bc; Z80.bc = Z80.bc2; Z80.bc2 = tmp; \ + tmp = Z80.de; Z80.de = Z80.de2; Z80.de2 = tmp; \ + tmp = Z80.hl; Z80.hl = Z80.hl2; Z80.hl2 = tmp; \ +} + +/*************************************************************** + * EX (SP),r16 + ***************************************************************/ +#define EXSP(DR) \ +{ \ + PAIR tmp = { { 0, 0, 0, 0 } }; \ + RM16( SPD, &tmp ); \ + WM16( SPD, &Z80.DR ); \ + Z80.DR = tmp; \ + WZ = Z80.DR.d; \ +} + + +/*************************************************************** + * ADD16 + ***************************************************************/ +#define ADD16(DR,SR) \ +{ \ + UINT32 res = Z80.DR.d + Z80.SR.d; \ + WZ = Z80.DR.d + 1; \ + F = (F & (SF | ZF | VF)) | \ + (((Z80.DR.d ^ res ^ Z80.SR.d) >> 8) & HF) | \ + ((res >> 16) & CF) | ((res >> 8) & (YF | XF)); \ + Z80.DR.w.l = (UINT16)res; \ +} + +/*************************************************************** + * ADC r16,r16 + ***************************************************************/ +#define ADC16(Reg) \ +{ \ + UINT32 res = HLD + Z80.Reg.d + (F & CF); \ + WZ = HL + 1; \ + F = (((HLD ^ res ^ Z80.Reg.d) >> 8) & HF) | \ + ((res >> 16) & CF) | \ + ((res >> 8) & (SF | YF | XF)) | \ + ((res & 0xffff) ? 0 : ZF) | \ + (((Z80.Reg.d ^ HLD ^ 0x8000) & (Z80.Reg.d ^ res) & 0x8000) >> 13); \ + HL = (UINT16)res; \ +} + +/*************************************************************** + * SBC r16,r16 + ***************************************************************/ +#define SBC16(Reg) \ +{ \ + UINT32 res = HLD - Z80.Reg.d - (F & CF); \ + WZ = HL + 1; \ + F = (((HLD ^ res ^ Z80.Reg.d) >> 8) & HF) | NF | \ + ((res >> 16) & CF) | \ + ((res >> 8) & (SF | YF | XF)) | \ + ((res & 0xffff) ? 0 : ZF) | \ + (((Z80.Reg.d ^ HLD) & (HLD ^ res) &0x8000) >> 13); \ + HL = (UINT16)res; \ +} + +/*************************************************************** + * RLC r8 + ***************************************************************/ +INLINE UINT8 RLC(UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = ((res << 1) | (res >> 7)) & 0xff; + F = SZP[res] | c; + return res; +} + +/*************************************************************** + * RRC r8 + ***************************************************************/ +INLINE UINT8 RRC(UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = ((res >> 1) | (res << 7)) & 0xff; + F = SZP[res] | c; + return res; +} + +/*************************************************************** + * RL r8 + ***************************************************************/ +INLINE UINT8 RL(UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = ((res << 1) | (F & CF)) & 0xff; + F = SZP[res] | c; + return res; +} + +/*************************************************************** + * RR r8 + ***************************************************************/ +INLINE UINT8 RR(UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = ((res >> 1) | (F << 7)) & 0xff; + F = SZP[res] | c; + return res; +} + +/*************************************************************** + * SLA r8 + ***************************************************************/ +INLINE UINT8 SLA(UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = (res << 1) & 0xff; + F = SZP[res] | c; + return res; +} + +/*************************************************************** + * SRA r8 + ***************************************************************/ +INLINE UINT8 SRA(UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = ((res >> 1) | (res & 0x80)) & 0xff; + F = SZP[res] | c; + return res; +} + +/*************************************************************** + * SLL r8 + ***************************************************************/ +INLINE UINT8 SLL(UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = ((res << 1) | 0x01) & 0xff; + F = SZP[res] | c; + return res; +} + +/*************************************************************** + * SRL r8 + ***************************************************************/ +INLINE UINT8 SRL(UINT8 value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = (res >> 1) & 0xff; + F = SZP[res] | c; + return res; +} + +/*************************************************************** + * BIT bit,r8 + ***************************************************************/ +#undef BIT +#define BIT(bit,reg) \ + F = (F & CF) | HF | (SZ_BIT[reg & (1<>8) & (YF|XF)) + +/*************************************************************** + * RES bit,r8 + ***************************************************************/ +INLINE UINT8 RES(UINT8 bit, UINT8 value) +{ + return value & ~(1< flag 5 */ \ + if( (A + io) & 0x08 ) F |= XF; /* bit 3 -> flag 3 */ \ + HL++; DE++; BC--; \ + if( BC ) F |= VF; \ +} + +/*************************************************************** + * CPI + ***************************************************************/ +#define CPI { \ + UINT8 val = RM(HL); \ + UINT8 res = A - val; \ + WZ++; \ + HL++; BC--; \ + F = (F & CF) | (SZ[res]&~(YF|XF)) | ((A^val^res)&HF) | NF; \ + if( F & HF ) res -= 1; \ + if( res & 0x02 ) F |= YF; /* bit 1 -> flag 5 */ \ + if( res & 0x08 ) F |= XF; /* bit 3 -> flag 3 */ \ + if( BC ) F |= VF; \ +} + +/*************************************************************** + * INI + ***************************************************************/ +#define INI { \ + unsigned t; \ + UINT8 io = IN(BC); \ + WZ = BC + 1; \ + CC(ex,0xa2); \ + B--; \ + WM( HL, io ); \ + HL++; \ + F = SZ[B]; \ + t = (unsigned)((C + 1) & 0xff) + (unsigned)io; \ + if( io & SF ) F |= NF; \ + if( t & 0x100 ) F |= HF | CF; \ + F |= SZP[(UINT8)(t & 0x07) ^ B] & PF; \ +} + +/*************************************************************** + * OUTI + ***************************************************************/ +#define OUTI { \ + unsigned t; \ + UINT8 io = RM(HL); \ + B--; \ + WZ = BC + 1; \ + OUT( BC, io ); \ + HL++; \ + F = SZ[B]; \ + t = (unsigned)L + (unsigned)io; \ + if( io & SF ) F |= NF; \ + if( t & 0x100 ) F |= HF | CF; \ + F |= SZP[(UINT8)(t & 0x07) ^ B] & PF; \ +} + +/*************************************************************** + * LDD + ***************************************************************/ +#define LDD { \ + UINT8 io = RM(HL); \ + WM( DE, io ); \ + F &= SF | ZF | CF; \ + if( (A + io) & 0x02 ) F |= YF; /* bit 1 -> flag 5 */ \ + if( (A + io) & 0x08 ) F |= XF; /* bit 3 -> flag 3 */ \ + HL--; DE--; BC--; \ + if( BC ) F |= VF; \ +} + +/*************************************************************** + * CPD + ***************************************************************/ +#define CPD { \ + UINT8 val = RM(HL); \ + UINT8 res = A - val; \ + WZ--; \ + HL--; BC--; \ + F = (F & CF) | (SZ[res]&~(YF|XF)) | ((A^val^res)&HF) | NF; \ + if( F & HF ) res -= 1; \ + if( res & 0x02 ) F |= YF; /* bit 1 -> flag 5 */ \ + if( res & 0x08 ) F |= XF; /* bit 3 -> flag 3 */ \ + if( BC ) F |= VF; \ +} + +/*************************************************************** + * IND + ***************************************************************/ +#define IND { \ + unsigned t; \ + UINT8 io = IN(BC); \ + WZ = BC - 1; \ + CC(ex,0xaa); \ + B--; \ + WM( HL, io ); \ + HL--; \ + F = SZ[B]; \ + t = ((unsigned)(C - 1) & 0xff) + (unsigned)io; \ + if( io & SF ) F |= NF; \ + if( t & 0x100 ) F |= HF | CF; \ + F |= SZP[(UINT8)(t & 0x07) ^ B] & PF; \ +} + +/*************************************************************** + * OUTD + ***************************************************************/ +#define OUTD { \ + unsigned t; \ + UINT8 io = RM(HL); \ + B--; \ + WZ = BC - 1; \ + OUT( BC, io ); \ + HL--; \ + F = SZ[B]; \ + t = (unsigned)L + (unsigned)io; \ + if( io & SF ) F |= NF; \ + if( t & 0x100 ) F |= HF | CF; \ + F |= SZP[(UINT8)(t & 0x07) ^ B] & PF; \ +} + +/*************************************************************** + * LDIR + ***************************************************************/ +#define LDIR \ + LDI; \ + if( BC ) \ + { \ + PC -= 2; \ + WZ = PC + 1; \ + CC(ex,0xb0); \ + } + +/*************************************************************** + * CPIR + ***************************************************************/ +#define CPIR \ + CPI; \ + if( BC && !(F & ZF) ) \ + { \ + PC -= 2; \ + WZ = PC + 1; \ + CC(ex,0xb1); \ + } + +/*************************************************************** + * INIR + ***************************************************************/ +#define INIR \ + INI; \ + if( B ) \ + { \ + PC -= 2; \ + CC(ex,0xb2); \ + } + +/*************************************************************** + * OTIR + ***************************************************************/ +#define OTIR \ + OUTI; \ + if( B ) \ + { \ + PC -= 2; \ + CC(ex,0xb3); \ + } + +/*************************************************************** + * LDDR + ***************************************************************/ +#define LDDR \ + LDD; \ + if( BC ) \ + { \ + PC -= 2; \ + WZ = PC + 1; \ + CC(ex,0xb8); \ + } + +/*************************************************************** + * CPDR + ***************************************************************/ +#define CPDR \ + CPD; \ + if( BC && !(F & ZF) ) \ + { \ + PC -= 2; \ + WZ = PC + 1; \ + CC(ex,0xb9); \ + } + +/*************************************************************** + * INDR + ***************************************************************/ +#define INDR \ + IND; \ + if( B ) \ + { \ + PC -= 2; \ + CC(ex,0xba); \ + } + +/*************************************************************** + * OTDR + ***************************************************************/ +#define OTDR \ + OUTD; \ + if( B ) \ + { \ + PC -= 2; \ + CC(ex,0xbb); \ + } + +/*************************************************************** + * EI + ***************************************************************/ +#define EI { \ + IFF1 = IFF2 = 1; \ + Z80.after_ei = TRUE; \ +} + +/********************************************************** + * opcodes with CB prefix + * rotate, shift and bit operations + **********************************************************/ +OP(cb,00) { B = RLC(B); } /* RLC B */ +OP(cb,01) { C = RLC(C); } /* RLC C */ +OP(cb,02) { D = RLC(D); } /* RLC D */ +OP(cb,03) { E = RLC(E); } /* RLC E */ +OP(cb,04) { H = RLC(H); } /* RLC H */ +OP(cb,05) { L = RLC(L); } /* RLC L */ +OP(cb,06) { WM( HL, RLC(RM(HL)) ); } /* RLC (HL) */ +OP(cb,07) { A = RLC(A); } /* RLC A */ + +OP(cb,08) { B = RRC(B); } /* RRC B */ +OP(cb,09) { C = RRC(C); } /* RRC C */ +OP(cb,0a) { D = RRC(D); } /* RRC D */ +OP(cb,0b) { E = RRC(E); } /* RRC E */ +OP(cb,0c) { H = RRC(H); } /* RRC H */ +OP(cb,0d) { L = RRC(L); } /* RRC L */ +OP(cb,0e) { WM( HL, RRC(RM(HL)) ); } /* RRC (HL) */ +OP(cb,0f) { A = RRC(A); } /* RRC A */ + +OP(cb,10) { B = RL(B); } /* RL B */ +OP(cb,11) { C = RL(C); } /* RL C */ +OP(cb,12) { D = RL(D); } /* RL D */ +OP(cb,13) { E = RL(E); } /* RL E */ +OP(cb,14) { H = RL(H); } /* RL H */ +OP(cb,15) { L = RL(L); } /* RL L */ +OP(cb,16) { WM( HL, RL(RM(HL)) ); } /* RL (HL) */ +OP(cb,17) { A = RL(A); } /* RL A */ + +OP(cb,18) { B = RR(B); } /* RR B */ +OP(cb,19) { C = RR(C); } /* RR C */ +OP(cb,1a) { D = RR(D); } /* RR D */ +OP(cb,1b) { E = RR(E); } /* RR E */ +OP(cb,1c) { H = RR(H); } /* RR H */ +OP(cb,1d) { L = RR(L); } /* RR L */ +OP(cb,1e) { WM( HL, RR(RM(HL)) ); } /* RR (HL) */ +OP(cb,1f) { A = RR(A); } /* RR A */ + +OP(cb,20) { B = SLA(B); } /* SLA B */ +OP(cb,21) { C = SLA(C); } /* SLA C */ +OP(cb,22) { D = SLA(D); } /* SLA D */ +OP(cb,23) { E = SLA(E); } /* SLA E */ +OP(cb,24) { H = SLA(H); } /* SLA H */ +OP(cb,25) { L = SLA(L); } /* SLA L */ +OP(cb,26) { WM( HL, SLA(RM(HL)) ); } /* SLA (HL) */ +OP(cb,27) { A = SLA(A); } /* SLA A */ + +OP(cb,28) { B = SRA(B); } /* SRA B */ +OP(cb,29) { C = SRA(C); } /* SRA C */ +OP(cb,2a) { D = SRA(D); } /* SRA D */ +OP(cb,2b) { E = SRA(E); } /* SRA E */ +OP(cb,2c) { H = SRA(H); } /* SRA H */ +OP(cb,2d) { L = SRA(L); } /* SRA L */ +OP(cb,2e) { WM( HL, SRA(RM(HL)) ); } /* SRA (HL) */ +OP(cb,2f) { A = SRA(A); } /* SRA A */ + +OP(cb,30) { B = SLL(B); } /* SLL B */ +OP(cb,31) { C = SLL(C); } /* SLL C */ +OP(cb,32) { D = SLL(D); } /* SLL D */ +OP(cb,33) { E = SLL(E); } /* SLL E */ +OP(cb,34) { H = SLL(H); } /* SLL H */ +OP(cb,35) { L = SLL(L); } /* SLL L */ +OP(cb,36) { WM( HL, SLL(RM(HL)) ); } /* SLL (HL) */ +OP(cb,37) { A = SLL(A); } /* SLL A */ + +OP(cb,38) { B = SRL(B); } /* SRL B */ +OP(cb,39) { C = SRL(C); } /* SRL C */ +OP(cb,3a) { D = SRL(D); } /* SRL D */ +OP(cb,3b) { E = SRL(E); } /* SRL E */ +OP(cb,3c) { H = SRL(H); } /* SRL H */ +OP(cb,3d) { L = SRL(L); } /* SRL L */ +OP(cb,3e) { WM( HL, SRL(RM(HL)) ); } /* SRL (HL) */ +OP(cb,3f) { A = SRL(A); } /* SRL A */ + +OP(cb,40) { BIT(0,B); } /* BIT 0,B */ +OP(cb,41) { BIT(0,C); } /* BIT 0,C */ +OP(cb,42) { BIT(0,D); } /* BIT 0,D */ +OP(cb,43) { BIT(0,E); } /* BIT 0,E */ +OP(cb,44) { BIT(0,H); } /* BIT 0,H */ +OP(cb,45) { BIT(0,L); } /* BIT 0,L */ +OP(cb,46) { BIT_HL(0,RM(HL)); } /* BIT 0,(HL) */ +OP(cb,47) { BIT(0,A); } /* BIT 0,A */ + +OP(cb,48) { BIT(1,B); } /* BIT 1,B */ +OP(cb,49) { BIT(1,C); } /* BIT 1,C */ +OP(cb,4a) { BIT(1,D); } /* BIT 1,D */ +OP(cb,4b) { BIT(1,E); } /* BIT 1,E */ +OP(cb,4c) { BIT(1,H); } /* BIT 1,H */ +OP(cb,4d) { BIT(1,L); } /* BIT 1,L */ +OP(cb,4e) { BIT_HL(1,RM(HL)); } /* BIT 1,(HL) */ +OP(cb,4f) { BIT(1,A); } /* BIT 1,A */ + +OP(cb,50) { BIT(2,B); } /* BIT 2,B */ +OP(cb,51) { BIT(2,C); } /* BIT 2,C */ +OP(cb,52) { BIT(2,D); } /* BIT 2,D */ +OP(cb,53) { BIT(2,E); } /* BIT 2,E */ +OP(cb,54) { BIT(2,H); } /* BIT 2,H */ +OP(cb,55) { BIT(2,L); } /* BIT 2,L */ +OP(cb,56) { BIT_HL(2,RM(HL)); } /* BIT 2,(HL) */ +OP(cb,57) { BIT(2,A); } /* BIT 2,A */ + +OP(cb,58) { BIT(3,B); } /* BIT 3,B */ +OP(cb,59) { BIT(3,C); } /* BIT 3,C */ +OP(cb,5a) { BIT(3,D); } /* BIT 3,D */ +OP(cb,5b) { BIT(3,E); } /* BIT 3,E */ +OP(cb,5c) { BIT(3,H); } /* BIT 3,H */ +OP(cb,5d) { BIT(3,L); } /* BIT 3,L */ +OP(cb,5e) { BIT_HL(3,RM(HL)); } /* BIT 3,(HL) */ +OP(cb,5f) { BIT(3,A); } /* BIT 3,A */ + +OP(cb,60) { BIT(4,B); } /* BIT 4,B */ +OP(cb,61) { BIT(4,C); } /* BIT 4,C */ +OP(cb,62) { BIT(4,D); } /* BIT 4,D */ +OP(cb,63) { BIT(4,E); } /* BIT 4,E */ +OP(cb,64) { BIT(4,H); } /* BIT 4,H */ +OP(cb,65) { BIT(4,L); } /* BIT 4,L */ +OP(cb,66) { BIT_HL(4,RM(HL)); } /* BIT 4,(HL) */ +OP(cb,67) { BIT(4,A); } /* BIT 4,A */ + +OP(cb,68) { BIT(5,B); } /* BIT 5,B */ +OP(cb,69) { BIT(5,C); } /* BIT 5,C */ +OP(cb,6a) { BIT(5,D); } /* BIT 5,D */ +OP(cb,6b) { BIT(5,E); } /* BIT 5,E */ +OP(cb,6c) { BIT(5,H); } /* BIT 5,H */ +OP(cb,6d) { BIT(5,L); } /* BIT 5,L */ +OP(cb,6e) { BIT_HL(5,RM(HL)); } /* BIT 5,(HL) */ +OP(cb,6f) { BIT(5,A); } /* BIT 5,A */ + +OP(cb,70) { BIT(6,B); } /* BIT 6,B */ +OP(cb,71) { BIT(6,C); } /* BIT 6,C */ +OP(cb,72) { BIT(6,D); } /* BIT 6,D */ +OP(cb,73) { BIT(6,E); } /* BIT 6,E */ +OP(cb,74) { BIT(6,H); } /* BIT 6,H */ +OP(cb,75) { BIT(6,L); } /* BIT 6,L */ +OP(cb,76) { BIT_HL(6,RM(HL)); } /* BIT 6,(HL) */ +OP(cb,77) { BIT(6,A); } /* BIT 6,A */ + +OP(cb,78) { BIT(7,B); } /* BIT 7,B */ +OP(cb,79) { BIT(7,C); } /* BIT 7,C */ +OP(cb,7a) { BIT(7,D); } /* BIT 7,D */ +OP(cb,7b) { BIT(7,E); } /* BIT 7,E */ +OP(cb,7c) { BIT(7,H); } /* BIT 7,H */ +OP(cb,7d) { BIT(7,L); } /* BIT 7,L */ +OP(cb,7e) { BIT_HL(7,RM(HL)); } /* BIT 7,(HL) */ +OP(cb,7f) { BIT(7,A); } /* BIT 7,A */ + +OP(cb,80) { B = RES(0,B); } /* RES 0,B */ +OP(cb,81) { C = RES(0,C); } /* RES 0,C */ +OP(cb,82) { D = RES(0,D); } /* RES 0,D */ +OP(cb,83) { E = RES(0,E); } /* RES 0,E */ +OP(cb,84) { H = RES(0,H); } /* RES 0,H */ +OP(cb,85) { L = RES(0,L); } /* RES 0,L */ +OP(cb,86) { WM( HL, RES(0,RM(HL)) ); } /* RES 0,(HL) */ +OP(cb,87) { A = RES(0,A); } /* RES 0,A */ + +OP(cb,88) { B = RES(1,B); } /* RES 1,B */ +OP(cb,89) { C = RES(1,C); } /* RES 1,C */ +OP(cb,8a) { D = RES(1,D); } /* RES 1,D */ +OP(cb,8b) { E = RES(1,E); } /* RES 1,E */ +OP(cb,8c) { H = RES(1,H); } /* RES 1,H */ +OP(cb,8d) { L = RES(1,L); } /* RES 1,L */ +OP(cb,8e) { WM( HL, RES(1,RM(HL)) ); } /* RES 1,(HL) */ +OP(cb,8f) { A = RES(1,A); } /* RES 1,A */ + +OP(cb,90) { B = RES(2,B); } /* RES 2,B */ +OP(cb,91) { C = RES(2,C); } /* RES 2,C */ +OP(cb,92) { D = RES(2,D); } /* RES 2,D */ +OP(cb,93) { E = RES(2,E); } /* RES 2,E */ +OP(cb,94) { H = RES(2,H); } /* RES 2,H */ +OP(cb,95) { L = RES(2,L); } /* RES 2,L */ +OP(cb,96) { WM( HL, RES(2,RM(HL)) ); } /* RES 2,(HL) */ +OP(cb,97) { A = RES(2,A); } /* RES 2,A */ + +OP(cb,98) { B = RES(3,B); } /* RES 3,B */ +OP(cb,99) { C = RES(3,C); } /* RES 3,C */ +OP(cb,9a) { D = RES(3,D); } /* RES 3,D */ +OP(cb,9b) { E = RES(3,E); } /* RES 3,E */ +OP(cb,9c) { H = RES(3,H); } /* RES 3,H */ +OP(cb,9d) { L = RES(3,L); } /* RES 3,L */ +OP(cb,9e) { WM( HL, RES(3,RM(HL)) ); } /* RES 3,(HL) */ +OP(cb,9f) { A = RES(3,A); } /* RES 3,A */ + +OP(cb,a0) { B = RES(4,B); } /* RES 4,B */ +OP(cb,a1) { C = RES(4,C); } /* RES 4,C */ +OP(cb,a2) { D = RES(4,D); } /* RES 4,D */ +OP(cb,a3) { E = RES(4,E); } /* RES 4,E */ +OP(cb,a4) { H = RES(4,H); } /* RES 4,H */ +OP(cb,a5) { L = RES(4,L); } /* RES 4,L */ +OP(cb,a6) { WM( HL, RES(4,RM(HL)) ); } /* RES 4,(HL) */ +OP(cb,a7) { A = RES(4,A); } /* RES 4,A */ + +OP(cb,a8) { B = RES(5,B); } /* RES 5,B */ +OP(cb,a9) { C = RES(5,C); } /* RES 5,C */ +OP(cb,aa) { D = RES(5,D); } /* RES 5,D */ +OP(cb,ab) { E = RES(5,E); } /* RES 5,E */ +OP(cb,ac) { H = RES(5,H); } /* RES 5,H */ +OP(cb,ad) { L = RES(5,L); } /* RES 5,L */ +OP(cb,ae) { WM( HL, RES(5,RM(HL)) ); } /* RES 5,(HL) */ +OP(cb,af) { A = RES(5,A); } /* RES 5,A */ + +OP(cb,b0) { B = RES(6,B); } /* RES 6,B */ +OP(cb,b1) { C = RES(6,C); } /* RES 6,C */ +OP(cb,b2) { D = RES(6,D); } /* RES 6,D */ +OP(cb,b3) { E = RES(6,E); } /* RES 6,E */ +OP(cb,b4) { H = RES(6,H); } /* RES 6,H */ +OP(cb,b5) { L = RES(6,L); } /* RES 6,L */ +OP(cb,b6) { WM( HL, RES(6,RM(HL)) ); } /* RES 6,(HL) */ +OP(cb,b7) { A = RES(6,A); } /* RES 6,A */ + +OP(cb,b8) { B = RES(7,B); } /* RES 7,B */ +OP(cb,b9) { C = RES(7,C); } /* RES 7,C */ +OP(cb,ba) { D = RES(7,D); } /* RES 7,D */ +OP(cb,bb) { E = RES(7,E); } /* RES 7,E */ +OP(cb,bc) { H = RES(7,H); } /* RES 7,H */ +OP(cb,bd) { L = RES(7,L); } /* RES 7,L */ +OP(cb,be) { WM( HL, RES(7,RM(HL)) ); } /* RES 7,(HL) */ +OP(cb,bf) { A = RES(7,A); } /* RES 7,A */ + +OP(cb,c0) { B = SET(0,B); } /* SET 0,B */ +OP(cb,c1) { C = SET(0,C); } /* SET 0,C */ +OP(cb,c2) { D = SET(0,D); } /* SET 0,D */ +OP(cb,c3) { E = SET(0,E); } /* SET 0,E */ +OP(cb,c4) { H = SET(0,H); } /* SET 0,H */ +OP(cb,c5) { L = SET(0,L); } /* SET 0,L */ +OP(cb,c6) { WM( HL, SET(0,RM(HL)) ); } /* SET 0,(HL) */ +OP(cb,c7) { A = SET(0,A); } /* SET 0,A */ + +OP(cb,c8) { B = SET(1,B); } /* SET 1,B */ +OP(cb,c9) { C = SET(1,C); } /* SET 1,C */ +OP(cb,ca) { D = SET(1,D); } /* SET 1,D */ +OP(cb,cb) { E = SET(1,E); } /* SET 1,E */ +OP(cb,cc) { H = SET(1,H); } /* SET 1,H */ +OP(cb,cd) { L = SET(1,L); } /* SET 1,L */ +OP(cb,ce) { WM( HL, SET(1,RM(HL)) ); } /* SET 1,(HL) */ +OP(cb,cf) { A = SET(1,A); } /* SET 1,A */ + +OP(cb,d0) { B = SET(2,B); } /* SET 2,B */ +OP(cb,d1) { C = SET(2,C); } /* SET 2,C */ +OP(cb,d2) { D = SET(2,D); } /* SET 2,D */ +OP(cb,d3) { E = SET(2,E); } /* SET 2,E */ +OP(cb,d4) { H = SET(2,H); } /* SET 2,H */ +OP(cb,d5) { L = SET(2,L); } /* SET 2,L */ +OP(cb,d6) { WM( HL, SET(2,RM(HL)) ); } /* SET 2,(HL) */ +OP(cb,d7) { A = SET(2,A); } /* SET 2,A */ + +OP(cb,d8) { B = SET(3,B); } /* SET 3,B */ +OP(cb,d9) { C = SET(3,C); } /* SET 3,C */ +OP(cb,da) { D = SET(3,D); } /* SET 3,D */ +OP(cb,db) { E = SET(3,E); } /* SET 3,E */ +OP(cb,dc) { H = SET(3,H); } /* SET 3,H */ +OP(cb,dd) { L = SET(3,L); } /* SET 3,L */ +OP(cb,de) { WM( HL, SET(3,RM(HL)) ); } /* SET 3,(HL) */ +OP(cb,df) { A = SET(3,A); } /* SET 3,A */ + +OP(cb,e0) { B = SET(4,B); } /* SET 4,B */ +OP(cb,e1) { C = SET(4,C); } /* SET 4,C */ +OP(cb,e2) { D = SET(4,D); } /* SET 4,D */ +OP(cb,e3) { E = SET(4,E); } /* SET 4,E */ +OP(cb,e4) { H = SET(4,H); } /* SET 4,H */ +OP(cb,e5) { L = SET(4,L); } /* SET 4,L */ +OP(cb,e6) { WM( HL, SET(4,RM(HL)) ); } /* SET 4,(HL) */ +OP(cb,e7) { A = SET(4,A); } /* SET 4,A */ + +OP(cb,e8) { B = SET(5,B); } /* SET 5,B */ +OP(cb,e9) { C = SET(5,C); } /* SET 5,C */ +OP(cb,ea) { D = SET(5,D); } /* SET 5,D */ +OP(cb,eb) { E = SET(5,E); } /* SET 5,E */ +OP(cb,ec) { H = SET(5,H); } /* SET 5,H */ +OP(cb,ed) { L = SET(5,L); } /* SET 5,L */ +OP(cb,ee) { WM( HL, SET(5,RM(HL)) ); } /* SET 5,(HL) */ +OP(cb,ef) { A = SET(5,A); } /* SET 5,A */ + +OP(cb,f0) { B = SET(6,B); } /* SET 6,B */ +OP(cb,f1) { C = SET(6,C); } /* SET 6,C */ +OP(cb,f2) { D = SET(6,D); } /* SET 6,D */ +OP(cb,f3) { E = SET(6,E); } /* SET 6,E */ +OP(cb,f4) { H = SET(6,H); } /* SET 6,H */ +OP(cb,f5) { L = SET(6,L); } /* SET 6,L */ +OP(cb,f6) { WM( HL, SET(6,RM(HL)) ); } /* SET 6,(HL) */ +OP(cb,f7) { A = SET(6,A); } /* SET 6,A */ + +OP(cb,f8) { B = SET(7,B); } /* SET 7,B */ +OP(cb,f9) { C = SET(7,C); } /* SET 7,C */ +OP(cb,fa) { D = SET(7,D); } /* SET 7,D */ +OP(cb,fb) { E = SET(7,E); } /* SET 7,E */ +OP(cb,fc) { H = SET(7,H); } /* SET 7,H */ +OP(cb,fd) { L = SET(7,L); } /* SET 7,L */ +OP(cb,fe) { WM( HL, SET(7,RM(HL)) ); } /* SET 7,(HL) */ +OP(cb,ff) { A = SET(7,A); } /* SET 7,A */ + + +/********************************************************** +* opcodes with DD/FD CB prefix +* rotate, shift and bit operations with (IX+o) +**********************************************************/ +OP(xycb,00) { B = RLC( RM(EA) ); WM( EA,B ); } /* RLC B=(XY+o) */ +OP(xycb,01) { C = RLC( RM(EA) ); WM( EA,C ); } /* RLC C=(XY+o) */ +OP(xycb,02) { D = RLC( RM(EA) ); WM( EA,D ); } /* RLC D=(XY+o) */ +OP(xycb,03) { E = RLC( RM(EA) ); WM( EA,E ); } /* RLC E=(XY+o) */ +OP(xycb,04) { H = RLC( RM(EA) ); WM( EA,H ); } /* RLC H=(XY+o) */ +OP(xycb,05) { L = RLC( RM(EA) ); WM( EA,L ); } /* RLC L=(XY+o) */ +OP(xycb,06) { WM( EA, RLC( RM(EA) ) ); } /* RLC (XY+o) */ +OP(xycb,07) { A = RLC( RM(EA) ); WM( EA,A ); } /* RLC A=(XY+o) */ + +OP(xycb,08) { B = RRC( RM(EA) ); WM( EA,B ); } /* RRC B=(XY+o) */ +OP(xycb,09) { C = RRC( RM(EA) ); WM( EA,C ); } /* RRC C=(XY+o) */ +OP(xycb,0a) { D = RRC( RM(EA) ); WM( EA,D ); } /* RRC D=(XY+o) */ +OP(xycb,0b) { E = RRC( RM(EA) ); WM( EA,E ); } /* RRC E=(XY+o) */ +OP(xycb,0c) { H = RRC( RM(EA) ); WM( EA,H ); } /* RRC H=(XY+o) */ +OP(xycb,0d) { L = RRC( RM(EA) ); WM( EA,L ); } /* RRC L=(XY+o) */ +OP(xycb,0e) { WM( EA,RRC( RM(EA) ) ); } /* RRC (XY+o) */ +OP(xycb,0f) { A = RRC( RM(EA) ); WM( EA,A ); } /* RRC A=(XY+o) */ + +OP(xycb,10) { B = RL( RM(EA) ); WM( EA,B ); } /* RL B=(XY+o) */ +OP(xycb,11) { C = RL( RM(EA) ); WM( EA,C ); } /* RL C=(XY+o) */ +OP(xycb,12) { D = RL( RM(EA) ); WM( EA,D ); } /* RL D=(XY+o) */ +OP(xycb,13) { E = RL( RM(EA) ); WM( EA,E ); } /* RL E=(XY+o) */ +OP(xycb,14) { H = RL( RM(EA) ); WM( EA,H ); } /* RL H=(XY+o) */ +OP(xycb,15) { L = RL( RM(EA) ); WM( EA,L ); } /* RL L=(XY+o) */ +OP(xycb,16) { WM( EA,RL( RM(EA) ) ); } /* RL (XY+o) */ +OP(xycb,17) { A = RL( RM(EA) ); WM( EA,A ); } /* RL A=(XY+o) */ + +OP(xycb,18) { B = RR( RM(EA) ); WM( EA,B ); } /* RR B=(XY+o) */ +OP(xycb,19) { C = RR( RM(EA) ); WM( EA,C ); } /* RR C=(XY+o) */ +OP(xycb,1a) { D = RR( RM(EA) ); WM( EA,D ); } /* RR D=(XY+o) */ +OP(xycb,1b) { E = RR( RM(EA) ); WM( EA,E ); } /* RR E=(XY+o) */ +OP(xycb,1c) { H = RR( RM(EA) ); WM( EA,H ); } /* RR H=(XY+o) */ +OP(xycb,1d) { L = RR( RM(EA) ); WM( EA,L ); } /* RR L=(XY+o) */ +OP(xycb,1e) { WM( EA,RR( RM(EA) ) ); } /* RR (XY+o) */ +OP(xycb,1f) { A = RR( RM(EA) ); WM( EA,A ); } /* RR A=(XY+o) */ + +OP(xycb,20) { B = SLA( RM(EA) ); WM( EA,B ); } /* SLA B=(XY+o) */ +OP(xycb,21) { C = SLA( RM(EA) ); WM( EA,C ); } /* SLA C=(XY+o) */ +OP(xycb,22) { D = SLA( RM(EA) ); WM( EA,D ); } /* SLA D=(XY+o) */ +OP(xycb,23) { E = SLA( RM(EA) ); WM( EA,E ); } /* SLA E=(XY+o) */ +OP(xycb,24) { H = SLA( RM(EA) ); WM( EA,H ); } /* SLA H=(XY+o) */ +OP(xycb,25) { L = SLA( RM(EA) ); WM( EA,L ); } /* SLA L=(XY+o) */ +OP(xycb,26) { WM( EA,SLA( RM(EA) ) ); } /* SLA (XY+o) */ +OP(xycb,27) { A = SLA( RM(EA) ); WM( EA,A ); } /* SLA A=(XY+o) */ + +OP(xycb,28) { B = SRA( RM(EA) ); WM( EA,B ); } /* SRA B=(XY+o) */ +OP(xycb,29) { C = SRA( RM(EA) ); WM( EA,C ); } /* SRA C=(XY+o) */ +OP(xycb,2a) { D = SRA( RM(EA) ); WM( EA,D ); } /* SRA D=(XY+o) */ +OP(xycb,2b) { E = SRA( RM(EA) ); WM( EA,E ); } /* SRA E=(XY+o) */ +OP(xycb,2c) { H = SRA( RM(EA) ); WM( EA,H ); } /* SRA H=(XY+o) */ +OP(xycb,2d) { L = SRA( RM(EA) ); WM( EA,L ); } /* SRA L=(XY+o) */ +OP(xycb,2e) { WM( EA,SRA( RM(EA) ) ); } /* SRA (XY+o) */ +OP(xycb,2f) { A = SRA( RM(EA) ); WM( EA,A ); } /* SRA A=(XY+o) */ + +OP(xycb,30) { B = SLL( RM(EA) ); WM( EA,B ); } /* SLL B=(XY+o) */ +OP(xycb,31) { C = SLL( RM(EA) ); WM( EA,C ); } /* SLL C=(XY+o) */ +OP(xycb,32) { D = SLL( RM(EA) ); WM( EA,D ); } /* SLL D=(XY+o) */ +OP(xycb,33) { E = SLL( RM(EA) ); WM( EA,E ); } /* SLL E=(XY+o) */ +OP(xycb,34) { H = SLL( RM(EA) ); WM( EA,H ); } /* SLL H=(XY+o) */ +OP(xycb,35) { L = SLL( RM(EA) ); WM( EA,L ); } /* SLL L=(XY+o) */ +OP(xycb,36) { WM( EA,SLL( RM(EA) ) ); } /* SLL (XY+o) */ +OP(xycb,37) { A = SLL( RM(EA) ); WM( EA,A ); } /* SLL A=(XY+o) */ + +OP(xycb,38) { B = SRL( RM(EA) ); WM( EA,B ); } /* SRL B=(XY+o) */ +OP(xycb,39) { C = SRL( RM(EA) ); WM( EA,C ); } /* SRL C=(XY+o) */ +OP(xycb,3a) { D = SRL( RM(EA) ); WM( EA,D ); } /* SRL D=(XY+o) */ +OP(xycb,3b) { E = SRL( RM(EA) ); WM( EA,E ); } /* SRL E=(XY+o) */ +OP(xycb,3c) { H = SRL( RM(EA) ); WM( EA,H ); } /* SRL H=(XY+o) */ +OP(xycb,3d) { L = SRL( RM(EA) ); WM( EA,L ); } /* SRL L=(XY+o) */ +OP(xycb,3e) { WM( EA,SRL( RM(EA) ) ); } /* SRL (XY+o) */ +OP(xycb,3f) { A = SRL( RM(EA) ); WM( EA,A ); } /* SRL A=(XY+o) */ + +OP(xycb,40) { xycb_46(); } /* BIT 0,(XY+o) */ +OP(xycb,41) { xycb_46(); } /* BIT 0,(XY+o) */ +OP(xycb,42) { xycb_46(); } /* BIT 0,(XY+o) */ +OP(xycb,43) { xycb_46(); } /* BIT 0,(XY+o) */ +OP(xycb,44) { xycb_46(); } /* BIT 0,(XY+o) */ +OP(xycb,45) { xycb_46(); } /* BIT 0,(XY+o) */ +OP(xycb,46) { BIT_XY(0,RM(EA)); } /* BIT 0,(XY+o) */ +OP(xycb,47) { xycb_46(); } /* BIT 0,(XY+o) */ + +OP(xycb,48) { xycb_4e(); } /* BIT 1,(XY+o) */ +OP(xycb,49) { xycb_4e(); } /* BIT 1,(XY+o) */ +OP(xycb,4a) { xycb_4e(); } /* BIT 1,(XY+o) */ +OP(xycb,4b) { xycb_4e(); } /* BIT 1,(XY+o) */ +OP(xycb,4c) { xycb_4e(); } /* BIT 1,(XY+o) */ +OP(xycb,4d) { xycb_4e(); } /* BIT 1,(XY+o) */ +OP(xycb,4e) { BIT_XY(1,RM(EA)); } /* BIT 1,(XY+o) */ +OP(xycb,4f) { xycb_4e(); } /* BIT 1,(XY+o) */ + +OP(xycb,50) { xycb_56(); } /* BIT 2,(XY+o) */ +OP(xycb,51) { xycb_56(); } /* BIT 2,(XY+o) */ +OP(xycb,52) { xycb_56(); } /* BIT 2,(XY+o) */ +OP(xycb,53) { xycb_56(); } /* BIT 2,(XY+o) */ +OP(xycb,54) { xycb_56(); } /* BIT 2,(XY+o) */ +OP(xycb,55) { xycb_56(); } /* BIT 2,(XY+o) */ +OP(xycb,56) { BIT_XY(2,RM(EA)); } /* BIT 2,(XY+o) */ +OP(xycb,57) { xycb_56(); } /* BIT 2,(XY+o) */ + +OP(xycb,58) { xycb_5e(); } /* BIT 3,(XY+o) */ +OP(xycb,59) { xycb_5e(); } /* BIT 3,(XY+o) */ +OP(xycb,5a) { xycb_5e(); } /* BIT 3,(XY+o) */ +OP(xycb,5b) { xycb_5e(); } /* BIT 3,(XY+o) */ +OP(xycb,5c) { xycb_5e(); } /* BIT 3,(XY+o) */ +OP(xycb,5d) { xycb_5e(); } /* BIT 3,(XY+o) */ +OP(xycb,5e) { BIT_XY(3,RM(EA)); } /* BIT 3,(XY+o) */ +OP(xycb,5f) { xycb_5e(); } /* BIT 3,(XY+o) */ + +OP(xycb,60) { xycb_66(); } /* BIT 4,(XY+o) */ +OP(xycb,61) { xycb_66(); } /* BIT 4,(XY+o) */ +OP(xycb,62) { xycb_66(); } /* BIT 4,(XY+o) */ +OP(xycb,63) { xycb_66(); } /* BIT 4,(XY+o) */ +OP(xycb,64) { xycb_66(); } /* BIT 4,(XY+o) */ +OP(xycb,65) { xycb_66(); } /* BIT 4,(XY+o) */ +OP(xycb,66) { BIT_XY(4,RM(EA)); } /* BIT 4,(XY+o) */ +OP(xycb,67) { xycb_66(); } /* BIT 4,(XY+o) */ + +OP(xycb,68) { xycb_6e(); } /* BIT 5,(XY+o) */ +OP(xycb,69) { xycb_6e(); } /* BIT 5,(XY+o) */ +OP(xycb,6a) { xycb_6e(); } /* BIT 5,(XY+o) */ +OP(xycb,6b) { xycb_6e(); } /* BIT 5,(XY+o) */ +OP(xycb,6c) { xycb_6e(); } /* BIT 5,(XY+o) */ +OP(xycb,6d) { xycb_6e(); } /* BIT 5,(XY+o) */ +OP(xycb,6e) { BIT_XY(5,RM(EA)); } /* BIT 5,(XY+o) */ +OP(xycb,6f) { xycb_6e(); } /* BIT 5,(XY+o) */ + +OP(xycb,70) { xycb_76(); } /* BIT 6,(XY+o) */ +OP(xycb,71) { xycb_76(); } /* BIT 6,(XY+o) */ +OP(xycb,72) { xycb_76(); } /* BIT 6,(XY+o) */ +OP(xycb,73) { xycb_76(); } /* BIT 6,(XY+o) */ +OP(xycb,74) { xycb_76(); } /* BIT 6,(XY+o) */ +OP(xycb,75) { xycb_76(); } /* BIT 6,(XY+o) */ +OP(xycb,76) { BIT_XY(6,RM(EA)); } /* BIT 6,(XY+o) */ +OP(xycb,77) { xycb_76(); } /* BIT 6,(XY+o) */ + +OP(xycb,78) { xycb_7e(); } /* BIT 7,(XY+o) */ +OP(xycb,79) { xycb_7e(); } /* BIT 7,(XY+o) */ +OP(xycb,7a) { xycb_7e(); } /* BIT 7,(XY+o) */ +OP(xycb,7b) { xycb_7e(); } /* BIT 7,(XY+o) */ +OP(xycb,7c) { xycb_7e(); } /* BIT 7,(XY+o) */ +OP(xycb,7d) { xycb_7e(); } /* BIT 7,(XY+o) */ +OP(xycb,7e) { BIT_XY(7,RM(EA)); } /* BIT 7,(XY+o) */ +OP(xycb,7f) { xycb_7e(); } /* BIT 7,(XY+o) */ + +OP(xycb,80) { B = RES(0, RM(EA) ); WM( EA,B ); } /* RES 0,B=(XY+o) */ +OP(xycb,81) { C = RES(0, RM(EA) ); WM( EA,C ); } /* RES 0,C=(XY+o) */ +OP(xycb,82) { D = RES(0, RM(EA) ); WM( EA,D ); } /* RES 0,D=(XY+o) */ +OP(xycb,83) { E = RES(0, RM(EA) ); WM( EA,E ); } /* RES 0,E=(XY+o) */ +OP(xycb,84) { H = RES(0, RM(EA) ); WM( EA,H ); } /* RES 0,H=(XY+o) */ +OP(xycb,85) { L = RES(0, RM(EA) ); WM( EA,L ); } /* RES 0,L=(XY+o) */ +OP(xycb,86) { WM( EA, RES(0,RM(EA)) ); } /* RES 0,(XY+o) */ +OP(xycb,87) { A = RES(0, RM(EA) ); WM( EA,A ); } /* RES 0,A=(XY+o) */ + +OP(xycb,88) { B = RES(1, RM(EA) ); WM( EA,B ); } /* RES 1,B=(XY+o) */ +OP(xycb,89) { C = RES(1, RM(EA) ); WM( EA,C ); } /* RES 1,C=(XY+o) */ +OP(xycb,8a) { D = RES(1, RM(EA) ); WM( EA,D ); } /* RES 1,D=(XY+o) */ +OP(xycb,8b) { E = RES(1, RM(EA) ); WM( EA,E ); } /* RES 1,E=(XY+o) */ +OP(xycb,8c) { H = RES(1, RM(EA) ); WM( EA,H ); } /* RES 1,H=(XY+o) */ +OP(xycb,8d) { L = RES(1, RM(EA) ); WM( EA,L ); } /* RES 1,L=(XY+o) */ +OP(xycb,8e) { WM( EA, RES(1,RM(EA)) ); } /* RES 1,(XY+o) */ +OP(xycb,8f) { A = RES(1, RM(EA) ); WM( EA,A ); } /* RES 1,A=(XY+o) */ + +OP(xycb,90) { B = RES(2, RM(EA) ); WM( EA,B ); } /* RES 2,B=(XY+o) */ +OP(xycb,91) { C = RES(2, RM(EA) ); WM( EA,C ); } /* RES 2,C=(XY+o) */ +OP(xycb,92) { D = RES(2, RM(EA) ); WM( EA,D ); } /* RES 2,D=(XY+o) */ +OP(xycb,93) { E = RES(2, RM(EA) ); WM( EA,E ); } /* RES 2,E=(XY+o) */ +OP(xycb,94) { H = RES(2, RM(EA) ); WM( EA,H ); } /* RES 2,H=(XY+o) */ +OP(xycb,95) { L = RES(2, RM(EA) ); WM( EA,L ); } /* RES 2,L=(XY+o) */ +OP(xycb,96) { WM( EA, RES(2,RM(EA)) ); } /* RES 2,(XY+o) */ +OP(xycb,97) { A = RES(2, RM(EA) ); WM( EA,A ); } /* RES 2,A=(XY+o) */ + +OP(xycb,98) { B = RES(3, RM(EA) ); WM( EA,B ); } /* RES 3,B=(XY+o) */ +OP(xycb,99) { C = RES(3, RM(EA) ); WM( EA,C ); } /* RES 3,C=(XY+o) */ +OP(xycb,9a) { D = RES(3, RM(EA) ); WM( EA,D ); } /* RES 3,D=(XY+o) */ +OP(xycb,9b) { E = RES(3, RM(EA) ); WM( EA,E ); } /* RES 3,E=(XY+o) */ +OP(xycb,9c) { H = RES(3, RM(EA) ); WM( EA,H ); } /* RES 3,H=(XY+o) */ +OP(xycb,9d) { L = RES(3, RM(EA) ); WM( EA,L ); } /* RES 3,L=(XY+o) */ +OP(xycb,9e) { WM( EA, RES(3,RM(EA)) ); } /* RES 3,(XY+o) */ +OP(xycb,9f) { A = RES(3, RM(EA) ); WM( EA,A ); } /* RES 3,A=(XY+o) */ + +OP(xycb,a0) { B = RES(4, RM(EA) ); WM( EA,B ); } /* RES 4,B=(XY+o) */ +OP(xycb,a1) { C = RES(4, RM(EA) ); WM( EA,C ); } /* RES 4,C=(XY+o) */ +OP(xycb,a2) { D = RES(4, RM(EA) ); WM( EA,D ); } /* RES 4,D=(XY+o) */ +OP(xycb,a3) { E = RES(4, RM(EA) ); WM( EA,E ); } /* RES 4,E=(XY+o) */ +OP(xycb,a4) { H = RES(4, RM(EA) ); WM( EA,H ); } /* RES 4,H=(XY+o) */ +OP(xycb,a5) { L = RES(4, RM(EA) ); WM( EA,L ); } /* RES 4,L=(XY+o) */ +OP(xycb,a6) { WM( EA, RES(4,RM(EA)) ); } /* RES 4,(XY+o) */ +OP(xycb,a7) { A = RES(4, RM(EA) ); WM( EA,A ); } /* RES 4,A=(XY+o) */ + +OP(xycb,a8) { B = RES(5, RM(EA) ); WM( EA,B ); } /* RES 5,B=(XY+o) */ +OP(xycb,a9) { C = RES(5, RM(EA) ); WM( EA,C ); } /* RES 5,C=(XY+o) */ +OP(xycb,aa) { D = RES(5, RM(EA) ); WM( EA,D ); } /* RES 5,D=(XY+o) */ +OP(xycb,ab) { E = RES(5, RM(EA) ); WM( EA,E ); } /* RES 5,E=(XY+o) */ +OP(xycb,ac) { H = RES(5, RM(EA) ); WM( EA,H ); } /* RES 5,H=(XY+o) */ +OP(xycb,ad) { L = RES(5, RM(EA) ); WM( EA,L ); } /* RES 5,L=(XY+o) */ +OP(xycb,ae) { WM( EA, RES(5,RM(EA)) ); } /* RES 5,(XY+o) */ +OP(xycb,af) { A = RES(5, RM(EA) ); WM( EA,A ); } /* RES 5,A=(XY+o) */ + +OP(xycb,b0) { B = RES(6, RM(EA) ); WM( EA,B ); } /* RES 6,B=(XY+o) */ +OP(xycb,b1) { C = RES(6, RM(EA) ); WM( EA,C ); } /* RES 6,C=(XY+o) */ +OP(xycb,b2) { D = RES(6, RM(EA) ); WM( EA,D ); } /* RES 6,D=(XY+o) */ +OP(xycb,b3) { E = RES(6, RM(EA) ); WM( EA,E ); } /* RES 6,E=(XY+o) */ +OP(xycb,b4) { H = RES(6, RM(EA) ); WM( EA,H ); } /* RES 6,H=(XY+o) */ +OP(xycb,b5) { L = RES(6, RM(EA) ); WM( EA,L ); } /* RES 6,L=(XY+o) */ +OP(xycb,b6) { WM( EA, RES(6,RM(EA)) ); } /* RES 6,(XY+o) */ +OP(xycb,b7) { A = RES(6, RM(EA) ); WM( EA,A ); } /* RES 6,A=(XY+o) */ + +OP(xycb,b8) { B = RES(7, RM(EA) ); WM( EA,B ); } /* RES 7,B=(XY+o) */ +OP(xycb,b9) { C = RES(7, RM(EA) ); WM( EA,C ); } /* RES 7,C=(XY+o) */ +OP(xycb,ba) { D = RES(7, RM(EA) ); WM( EA,D ); } /* RES 7,D=(XY+o) */ +OP(xycb,bb) { E = RES(7, RM(EA) ); WM( EA,E ); } /* RES 7,E=(XY+o) */ +OP(xycb,bc) { H = RES(7, RM(EA) ); WM( EA,H ); } /* RES 7,H=(XY+o) */ +OP(xycb,bd) { L = RES(7, RM(EA) ); WM( EA,L ); } /* RES 7,L=(XY+o) */ +OP(xycb,be) { WM( EA, RES(7,RM(EA)) ); } /* RES 7,(XY+o) */ +OP(xycb,bf) { A = RES(7, RM(EA) ); WM( EA,A ); } /* RES 7,A=(XY+o) */ + +OP(xycb,c0) { B = SET(0, RM(EA) ); WM( EA,B ); } /* SET 0,B=(XY+o) */ +OP(xycb,c1) { C = SET(0, RM(EA) ); WM( EA,C ); } /* SET 0,C=(XY+o) */ +OP(xycb,c2) { D = SET(0, RM(EA) ); WM( EA,D ); } /* SET 0,D=(XY+o) */ +OP(xycb,c3) { E = SET(0, RM(EA) ); WM( EA,E ); } /* SET 0,E=(XY+o) */ +OP(xycb,c4) { H = SET(0, RM(EA) ); WM( EA,H ); } /* SET 0,H=(XY+o) */ +OP(xycb,c5) { L = SET(0, RM(EA) ); WM( EA,L ); } /* SET 0,L=(XY+o) */ +OP(xycb,c6) { WM( EA, SET(0,RM(EA)) ); } /* SET 0,(XY+o) */ +OP(xycb,c7) { A = SET(0, RM(EA) ); WM( EA,A ); } /* SET 0,A=(XY+o) */ + +OP(xycb,c8) { B = SET(1, RM(EA) ); WM( EA,B ); } /* SET 1,B=(XY+o) */ +OP(xycb,c9) { C = SET(1, RM(EA) ); WM( EA,C ); } /* SET 1,C=(XY+o) */ +OP(xycb,ca) { D = SET(1, RM(EA) ); WM( EA,D ); } /* SET 1,D=(XY+o) */ +OP(xycb,cb) { E = SET(1, RM(EA) ); WM( EA,E ); } /* SET 1,E=(XY+o) */ +OP(xycb,cc) { H = SET(1, RM(EA) ); WM( EA,H ); } /* SET 1,H=(XY+o) */ +OP(xycb,cd) { L = SET(1, RM(EA) ); WM( EA,L ); } /* SET 1,L=(XY+o) */ +OP(xycb,ce) { WM( EA, SET(1,RM(EA)) ); } /* SET 1,(XY+o) */ +OP(xycb,cf) { A = SET(1, RM(EA) ); WM( EA,A ); } /* SET 1,A=(XY+o) */ + +OP(xycb,d0) { B = SET(2, RM(EA) ); WM( EA,B ); } /* SET 2,B=(XY+o) */ +OP(xycb,d1) { C = SET(2, RM(EA) ); WM( EA,C ); } /* SET 2,C=(XY+o) */ +OP(xycb,d2) { D = SET(2, RM(EA) ); WM( EA,D ); } /* SET 2,D=(XY+o) */ +OP(xycb,d3) { E = SET(2, RM(EA) ); WM( EA,E ); } /* SET 2,E=(XY+o) */ +OP(xycb,d4) { H = SET(2, RM(EA) ); WM( EA,H ); } /* SET 2,H=(XY+o) */ +OP(xycb,d5) { L = SET(2, RM(EA) ); WM( EA,L ); } /* SET 2,L=(XY+o) */ +OP(xycb,d6) { WM( EA, SET(2,RM(EA)) ); } /* SET 2,(XY+o) */ +OP(xycb,d7) { A = SET(2, RM(EA) ); WM( EA,A ); } /* SET 2,A=(XY+o) */ + +OP(xycb,d8) { B = SET(3, RM(EA) ); WM( EA,B ); } /* SET 3,B=(XY+o) */ +OP(xycb,d9) { C = SET(3, RM(EA) ); WM( EA,C ); } /* SET 3,C=(XY+o) */ +OP(xycb,da) { D = SET(3, RM(EA) ); WM( EA,D ); } /* SET 3,D=(XY+o) */ +OP(xycb,db) { E = SET(3, RM(EA) ); WM( EA,E ); } /* SET 3,E=(XY+o) */ +OP(xycb,dc) { H = SET(3, RM(EA) ); WM( EA,H ); } /* SET 3,H=(XY+o) */ +OP(xycb,dd) { L = SET(3, RM(EA) ); WM( EA,L ); } /* SET 3,L=(XY+o) */ +OP(xycb,de) { WM( EA, SET(3,RM(EA)) ); } /* SET 3,(XY+o) */ +OP(xycb,df) { A = SET(3, RM(EA) ); WM( EA,A ); } /* SET 3,A=(XY+o) */ + +OP(xycb,e0) { B = SET(4, RM(EA) ); WM( EA,B ); } /* SET 4,B=(XY+o) */ +OP(xycb,e1) { C = SET(4, RM(EA) ); WM( EA,C ); } /* SET 4,C=(XY+o) */ +OP(xycb,e2) { D = SET(4, RM(EA) ); WM( EA,D ); } /* SET 4,D=(XY+o) */ +OP(xycb,e3) { E = SET(4, RM(EA) ); WM( EA,E ); } /* SET 4,E=(XY+o) */ +OP(xycb,e4) { H = SET(4, RM(EA) ); WM( EA,H ); } /* SET 4,H=(XY+o) */ +OP(xycb,e5) { L = SET(4, RM(EA) ); WM( EA,L ); } /* SET 4,L=(XY+o) */ +OP(xycb,e6) { WM( EA, SET(4,RM(EA)) ); } /* SET 4,(XY+o) */ +OP(xycb,e7) { A = SET(4, RM(EA) ); WM( EA,A ); } /* SET 4,A=(XY+o) */ + +OP(xycb,e8) { B = SET(5, RM(EA) ); WM( EA,B ); } /* SET 5,B=(XY+o) */ +OP(xycb,e9) { C = SET(5, RM(EA) ); WM( EA,C ); } /* SET 5,C=(XY+o) */ +OP(xycb,ea) { D = SET(5, RM(EA) ); WM( EA,D ); } /* SET 5,D=(XY+o) */ +OP(xycb,eb) { E = SET(5, RM(EA) ); WM( EA,E ); } /* SET 5,E=(XY+o) */ +OP(xycb,ec) { H = SET(5, RM(EA) ); WM( EA,H ); } /* SET 5,H=(XY+o) */ +OP(xycb,ed) { L = SET(5, RM(EA) ); WM( EA,L ); } /* SET 5,L=(XY+o) */ +OP(xycb,ee) { WM( EA, SET(5,RM(EA)) ); } /* SET 5,(XY+o) */ +OP(xycb,ef) { A = SET(5, RM(EA) ); WM( EA,A ); } /* SET 5,A=(XY+o) */ + +OP(xycb,f0) { B = SET(6, RM(EA) ); WM( EA,B ); } /* SET 6,B=(XY+o) */ +OP(xycb,f1) { C = SET(6, RM(EA) ); WM( EA,C ); } /* SET 6,C=(XY+o) */ +OP(xycb,f2) { D = SET(6, RM(EA) ); WM( EA,D ); } /* SET 6,D=(XY+o) */ +OP(xycb,f3) { E = SET(6, RM(EA) ); WM( EA,E ); } /* SET 6,E=(XY+o) */ +OP(xycb,f4) { H = SET(6, RM(EA) ); WM( EA,H ); } /* SET 6,H=(XY+o) */ +OP(xycb,f5) { L = SET(6, RM(EA) ); WM( EA,L ); } /* SET 6,L=(XY+o) */ +OP(xycb,f6) { WM( EA, SET(6,RM(EA)) ); } /* SET 6,(XY+o) */ +OP(xycb,f7) { A = SET(6, RM(EA) ); WM( EA,A ); } /* SET 6,A=(XY+o) */ + +OP(xycb,f8) { B = SET(7, RM(EA) ); WM( EA,B ); } /* SET 7,B=(XY+o) */ +OP(xycb,f9) { C = SET(7, RM(EA) ); WM( EA,C ); } /* SET 7,C=(XY+o) */ +OP(xycb,fa) { D = SET(7, RM(EA) ); WM( EA,D ); } /* SET 7,D=(XY+o) */ +OP(xycb,fb) { E = SET(7, RM(EA) ); WM( EA,E ); } /* SET 7,E=(XY+o) */ +OP(xycb,fc) { H = SET(7, RM(EA) ); WM( EA,H ); } /* SET 7,H=(XY+o) */ +OP(xycb,fd) { L = SET(7, RM(EA) ); WM( EA,L ); } /* SET 7,L=(XY+o) */ +OP(xycb,fe) { WM( EA, SET(7,RM(EA)) ); } /* SET 7,(XY+o) */ +OP(xycb,ff) { A = SET(7, RM(EA) ); WM( EA,A ); } /* SET 7,A=(XY+o) */ + +OP(illegal,1) { +#if VERBOSE + logerror("Z80 #%d ill. opcode $%02x $%02x\n", + cpu_getactivecpu(), cpu_readop((PCD-1)&0xffff), cpu_readop(PCD)); +#endif +} +/********************************************************** + * IX register related opcodes (DD prefix) + **********************************************************/ +OP(dd,00) { illegal_1(); op_00(); } /* DB DD */ +OP(dd,01) { illegal_1(); op_01(); } /* DB DD */ +OP(dd,02) { illegal_1(); op_02(); } /* DB DD */ +OP(dd,03) { illegal_1(); op_03(); } /* DB DD */ +OP(dd,04) { illegal_1(); op_04(); } /* DB DD */ +OP(dd,05) { illegal_1(); op_05(); } /* DB DD */ +OP(dd,06) { illegal_1(); op_06(); } /* DB DD */ +OP(dd,07) { illegal_1(); op_07(); } /* DB DD */ + +OP(dd,08) { illegal_1(); op_08(); } /* DB DD */ +OP(dd,09) { ADD16(ix,bc); } /* ADD IX,BC */ +OP(dd,0a) { illegal_1(); op_0a(); } /* DB DD */ +OP(dd,0b) { illegal_1(); op_0b(); } /* DB DD */ +OP(dd,0c) { illegal_1(); op_0c(); } /* DB DD */ +OP(dd,0d) { illegal_1(); op_0d(); } /* DB DD */ +OP(dd,0e) { illegal_1(); op_0e(); } /* DB DD */ +OP(dd,0f) { illegal_1(); op_0f(); } /* DB DD */ + +OP(dd,10) { illegal_1(); op_10(); } /* DB DD */ +OP(dd,11) { illegal_1(); op_11(); } /* DB DD */ +OP(dd,12) { illegal_1(); op_12(); } /* DB DD */ +OP(dd,13) { illegal_1(); op_13(); } /* DB DD */ +OP(dd,14) { illegal_1(); op_14(); } /* DB DD */ +OP(dd,15) { illegal_1(); op_15(); } /* DB DD */ +OP(dd,16) { illegal_1(); op_16(); } /* DB DD */ +OP(dd,17) { illegal_1(); op_17(); } /* DB DD */ + +OP(dd,18) { illegal_1(); op_18(); } /* DB DD */ +OP(dd,19) { ADD16(ix,de); } /* ADD IX,DE */ +OP(dd,1a) { illegal_1(); op_1a(); } /* DB DD */ +OP(dd,1b) { illegal_1(); op_1b(); } /* DB DD */ +OP(dd,1c) { illegal_1(); op_1c(); } /* DB DD */ +OP(dd,1d) { illegal_1(); op_1d(); } /* DB DD */ +OP(dd,1e) { illegal_1(); op_1e(); } /* DB DD */ +OP(dd,1f) { illegal_1(); op_1f(); } /* DB DD */ + +OP(dd,20) { illegal_1(); op_20(); } /* DB DD */ +OP(dd,21) { IX = ARG16(); } /* LD IX,w */ +OP(dd,22) { EA = ARG16(); WM16( EA, &Z80.ix ); WZ = EA+1; } /* LD (w),IX */ +OP(dd,23) { IX++; } /* INC IX */ +OP(dd,24) { HX = INC(HX); } /* INC HX */ +OP(dd,25) { HX = DEC(HX); } /* DEC HX */ +OP(dd,26) { HX = ARG(); } /* LD HX,n */ +OP(dd,27) { illegal_1(); op_27(); } /* DB DD */ + +OP(dd,28) { illegal_1(); op_28(); } /* DB DD */ +OP(dd,29) { ADD16(ix,ix); } /* ADD IX,IX */ +OP(dd,2a) { EA = ARG16(); RM16( EA, &Z80.ix ); WZ = EA+1; } /* LD IX,(w) */ +OP(dd,2b) { IX--; } /* DEC IX */ +OP(dd,2c) { LX = INC(LX); } /* INC LX */ +OP(dd,2d) { LX = DEC(LX); } /* DEC LX */ +OP(dd,2e) { LX = ARG(); } /* LD LX,n */ +OP(dd,2f) { illegal_1(); op_2f(); } /* DB DD */ + +OP(dd,30) { illegal_1(); op_30(); } /* DB DD */ +OP(dd,31) { illegal_1(); op_31(); } /* DB DD */ +OP(dd,32) { illegal_1(); op_32(); } /* DB DD */ +OP(dd,33) { illegal_1(); op_33(); } /* DB DD */ +OP(dd,34) { EAX; WM( EA, INC(RM(EA)) ); } /* INC (IX+o) */ +OP(dd,35) { EAX; WM( EA, DEC(RM(EA)) ); } /* DEC (IX+o) */ +OP(dd,36) { EAX; WM( EA, ARG() ); } /* LD (IX+o),n */ +OP(dd,37) { illegal_1(); op_37(); } /* DB DD */ + +OP(dd,38) { illegal_1(); op_38(); } /* DB DD */ +OP(dd,39) { ADD16(ix,sp); } /* ADD IX,SP */ +OP(dd,3a) { illegal_1(); op_3a(); } /* DB DD */ +OP(dd,3b) { illegal_1(); op_3b(); } /* DB DD */ +OP(dd,3c) { illegal_1(); op_3c(); } /* DB DD */ +OP(dd,3d) { illegal_1(); op_3d(); } /* DB DD */ +OP(dd,3e) { illegal_1(); op_3e(); } /* DB DD */ +OP(dd,3f) { illegal_1(); op_3f(); } /* DB DD */ + +OP(dd,40) { illegal_1(); op_40(); } /* DB DD */ +OP(dd,41) { illegal_1(); op_41(); } /* DB DD */ +OP(dd,42) { illegal_1(); op_42(); } /* DB DD */ +OP(dd,43) { illegal_1(); op_43(); } /* DB DD */ +OP(dd,44) { B = HX; } /* LD B,HX */ +OP(dd,45) { B = LX; } /* LD B,LX */ +OP(dd,46) { EAX; B = RM(EA); } /* LD B,(IX+o) */ +OP(dd,47) { illegal_1(); op_47(); } /* DB DD */ + +OP(dd,48) { illegal_1(); op_48(); } /* DB DD */ +OP(dd,49) { illegal_1(); op_49(); } /* DB DD */ +OP(dd,4a) { illegal_1(); op_4a(); } /* DB DD */ +OP(dd,4b) { illegal_1(); op_4b(); } /* DB DD */ +OP(dd,4c) { C = HX; } /* LD C,HX */ +OP(dd,4d) { C = LX; } /* LD C,LX */ +OP(dd,4e) { EAX; C = RM(EA); } /* LD C,(IX+o) */ +OP(dd,4f) { illegal_1(); op_4f(); } /* DB DD */ + +OP(dd,50) { illegal_1(); op_50(); } /* DB DD */ +OP(dd,51) { illegal_1(); op_51(); } /* DB DD */ +OP(dd,52) { illegal_1(); op_52(); } /* DB DD */ +OP(dd,53) { illegal_1(); op_53(); } /* DB DD */ +OP(dd,54) { D = HX; } /* LD D,HX */ +OP(dd,55) { D = LX; } /* LD D,LX */ +OP(dd,56) { EAX; D = RM(EA); } /* LD D,(IX+o) */ +OP(dd,57) { illegal_1(); op_57(); } /* DB DD */ + +OP(dd,58) { illegal_1(); op_58(); } /* DB DD */ +OP(dd,59) { illegal_1(); op_59(); } /* DB DD */ +OP(dd,5a) { illegal_1(); op_5a(); } /* DB DD */ +OP(dd,5b) { illegal_1(); op_5b(); } /* DB DD */ +OP(dd,5c) { E = HX; } /* LD E,HX */ +OP(dd,5d) { E = LX; } /* LD E,LX */ +OP(dd,5e) { EAX; E = RM(EA); } /* LD E,(IX+o) */ +OP(dd,5f) { illegal_1(); op_5f(); } /* DB DD */ + +OP(dd,60) { HX = B; } /* LD HX,B */ +OP(dd,61) { HX = C; } /* LD HX,C */ +OP(dd,62) { HX = D; } /* LD HX,D */ +OP(dd,63) { HX = E; } /* LD HX,E */ +OP(dd,64) { } /* LD HX,HX */ +OP(dd,65) { HX = LX; } /* LD HX,LX */ +OP(dd,66) { EAX; H = RM(EA); } /* LD H,(IX+o) */ +OP(dd,67) { HX = A; } /* LD HX,A */ + +OP(dd,68) { LX = B; } /* LD LX,B */ +OP(dd,69) { LX = C; } /* LD LX,C */ +OP(dd,6a) { LX = D; } /* LD LX,D */ +OP(dd,6b) { LX = E; } /* LD LX,E */ +OP(dd,6c) { LX = HX; } /* LD LX,HX */ +OP(dd,6d) { } /* LD LX,LX */ +OP(dd,6e) { EAX; L = RM(EA); } /* LD L,(IX+o) */ +OP(dd,6f) { LX = A; } /* LD LX,A */ + +OP(dd,70) { EAX; WM( EA, B ); } /* LD (IX+o),B */ +OP(dd,71) { EAX; WM( EA, C ); } /* LD (IX+o),C */ +OP(dd,72) { EAX; WM( EA, D ); } /* LD (IX+o),D */ +OP(dd,73) { EAX; WM( EA, E ); } /* LD (IX+o),E */ +OP(dd,74) { EAX; WM( EA, H ); } /* LD (IX+o),H */ +OP(dd,75) { EAX; WM( EA, L ); } /* LD (IX+o),L */ +OP(dd,76) { illegal_1(); op_76(); } /* DB DD */ +OP(dd,77) { EAX; WM( EA, A ); } /* LD (IX+o),A */ + +OP(dd,78) { illegal_1(); op_78(); } /* DB DD */ +OP(dd,79) { illegal_1(); op_79(); } /* DB DD */ +OP(dd,7a) { illegal_1(); op_7a(); } /* DB DD */ +OP(dd,7b) { illegal_1(); op_7b(); } /* DB DD */ +OP(dd,7c) { A = HX; } /* LD A,HX */ +OP(dd,7d) { A = LX; } /* LD A,LX */ +OP(dd,7e) { EAX; A = RM(EA); } /* LD A,(IX+o) */ +OP(dd,7f) { illegal_1(); op_7f(); } /* DB DD */ + +OP(dd,80) { illegal_1(); op_80(); } /* DB DD */ +OP(dd,81) { illegal_1(); op_81(); } /* DB DD */ +OP(dd,82) { illegal_1(); op_82(); } /* DB DD */ +OP(dd,83) { illegal_1(); op_83(); } /* DB DD */ +OP(dd,84) { ADD(HX); } /* ADD A,HX */ +OP(dd,85) { ADD(LX); } /* ADD A,LX */ +OP(dd,86) { EAX; ADD(RM(EA)); } /* ADD A,(IX+o) */ +OP(dd,87) { illegal_1(); op_87(); } /* DB DD */ + +OP(dd,88) { illegal_1(); op_88(); } /* DB DD */ +OP(dd,89) { illegal_1(); op_89(); } /* DB DD */ +OP(dd,8a) { illegal_1(); op_8a(); } /* DB DD */ +OP(dd,8b) { illegal_1(); op_8b(); } /* DB DD */ +OP(dd,8c) { ADC(HX); } /* ADC A,HX */ +OP(dd,8d) { ADC(LX); } /* ADC A,LX */ +OP(dd,8e) { EAX; ADC(RM(EA)); } /* ADC A,(IX+o) */ +OP(dd,8f) { illegal_1(); op_8f(); } /* DB DD */ + +OP(dd,90) { illegal_1(); op_90(); } /* DB DD */ +OP(dd,91) { illegal_1(); op_91(); } /* DB DD */ +OP(dd,92) { illegal_1(); op_92(); } /* DB DD */ +OP(dd,93) { illegal_1(); op_93(); } /* DB DD */ +OP(dd,94) { SUB(HX); } /* SUB HX */ +OP(dd,95) { SUB(LX); } /* SUB LX */ +OP(dd,96) { EAX; SUB(RM(EA)); } /* SUB (IX+o) */ +OP(dd,97) { illegal_1(); op_97(); } /* DB DD */ + +OP(dd,98) { illegal_1(); op_98(); } /* DB DD */ +OP(dd,99) { illegal_1(); op_99(); } /* DB DD */ +OP(dd,9a) { illegal_1(); op_9a(); } /* DB DD */ +OP(dd,9b) { illegal_1(); op_9b(); } /* DB DD */ +OP(dd,9c) { SBC(HX); } /* SBC A,HX */ +OP(dd,9d) { SBC(LX); } /* SBC A,LX */ +OP(dd,9e) { EAX; SBC(RM(EA)); } /* SBC A,(IX+o) */ +OP(dd,9f) { illegal_1(); op_9f(); } /* DB DD */ + +OP(dd,a0) { illegal_1(); op_a0(); } /* DB DD */ +OP(dd,a1) { illegal_1(); op_a1(); } /* DB DD */ +OP(dd,a2) { illegal_1(); op_a2(); } /* DB DD */ +OP(dd,a3) { illegal_1(); op_a3(); } /* DB DD */ +OP(dd,a4) { AND(HX); } /* AND HX */ +OP(dd,a5) { AND(LX); } /* AND LX */ +OP(dd,a6) { EAX; AND(RM(EA)); } /* AND (IX+o) */ +OP(dd,a7) { illegal_1(); op_a7(); } /* DB DD */ + +OP(dd,a8) { illegal_1(); op_a8(); } /* DB DD */ +OP(dd,a9) { illegal_1(); op_a9(); } /* DB DD */ +OP(dd,aa) { illegal_1(); op_aa(); } /* DB DD */ +OP(dd,ab) { illegal_1(); op_ab(); } /* DB DD */ +OP(dd,ac) { XOR(HX); } /* XOR HX */ +OP(dd,ad) { XOR(LX); } /* XOR LX */ +OP(dd,ae) { EAX; XOR(RM(EA)); } /* XOR (IX+o) */ +OP(dd,af) { illegal_1(); op_af(); } /* DB DD */ + +OP(dd,b0) { illegal_1(); op_b0(); } /* DB DD */ +OP(dd,b1) { illegal_1(); op_b1(); } /* DB DD */ +OP(dd,b2) { illegal_1(); op_b2(); } /* DB DD */ +OP(dd,b3) { illegal_1(); op_b3(); } /* DB DD */ +OP(dd,b4) { OR(HX); } /* OR HX */ +OP(dd,b5) { OR(LX); } /* OR LX */ +OP(dd,b6) { EAX; OR(RM(EA)); } /* OR (IX+o) */ +OP(dd,b7) { illegal_1(); op_b7(); } /* DB DD */ + +OP(dd,b8) { illegal_1(); op_b8(); } /* DB DD */ +OP(dd,b9) { illegal_1(); op_b9(); } /* DB DD */ +OP(dd,ba) { illegal_1(); op_ba(); } /* DB DD */ +OP(dd,bb) { illegal_1(); op_bb(); } /* DB DD */ +OP(dd,bc) { CP(HX); } /* CP HX */ +OP(dd,bd) { CP(LX); } /* CP LX */ +OP(dd,be) { EAX; CP(RM(EA)); } /* CP (IX+o) */ +OP(dd,bf) { illegal_1(); op_bf(); } /* DB DD */ + +OP(dd,c0) { illegal_1(); op_c0(); } /* DB DD */ +OP(dd,c1) { illegal_1(); op_c1(); } /* DB DD */ +OP(dd,c2) { illegal_1(); op_c2(); } /* DB DD */ +OP(dd,c3) { illegal_1(); op_c3(); } /* DB DD */ +OP(dd,c4) { illegal_1(); op_c4(); } /* DB DD */ +OP(dd,c5) { illegal_1(); op_c5(); } /* DB DD */ +OP(dd,c6) { illegal_1(); op_c6(); } /* DB DD */ +OP(dd,c7) { illegal_1(); op_c7(); } /* DB DD */ + +OP(dd,c8) { illegal_1(); op_c8(); } /* DB DD */ +OP(dd,c9) { illegal_1(); op_c9(); } /* DB DD */ +OP(dd,ca) { illegal_1(); op_ca(); } /* DB DD */ +OP(dd,cb) { EAX; EXEC(xycb,ARG()); } /* **** DD CB xx */ +OP(dd,cc) { illegal_1(); op_cc(); } /* DB DD */ +OP(dd,cd) { illegal_1(); op_cd(); } /* DB DD */ +OP(dd,ce) { illegal_1(); op_ce(); } /* DB DD */ +OP(dd,cf) { illegal_1(); op_cf(); } /* DB DD */ + +OP(dd,d0) { illegal_1(); op_d0(); } /* DB DD */ +OP(dd,d1) { illegal_1(); op_d1(); } /* DB DD */ +OP(dd,d2) { illegal_1(); op_d2(); } /* DB DD */ +OP(dd,d3) { illegal_1(); op_d3(); } /* DB DD */ +OP(dd,d4) { illegal_1(); op_d4(); } /* DB DD */ +OP(dd,d5) { illegal_1(); op_d5(); } /* DB DD */ +OP(dd,d6) { illegal_1(); op_d6(); } /* DB DD */ +OP(dd,d7) { illegal_1(); op_d7(); } /* DB DD */ + +OP(dd,d8) { illegal_1(); op_d8(); } /* DB DD */ +OP(dd,d9) { illegal_1(); op_d9(); } /* DB DD */ +OP(dd,da) { illegal_1(); op_da(); } /* DB DD */ +OP(dd,db) { illegal_1(); op_db(); } /* DB DD */ +OP(dd,dc) { illegal_1(); op_dc(); } /* DB DD */ +OP(dd,dd) { EXEC(dd,ROP()); } /* **** DD DD xx */ +OP(dd,de) { illegal_1(); op_de(); } /* DB DD */ +OP(dd,df) { illegal_1(); op_df(); } /* DB DD */ + +OP(dd,e0) { illegal_1(); op_e0(); } /* DB DD */ +OP(dd,e1) { POP( ix ); } /* POP IX */ +OP(dd,e2) { illegal_1(); op_e2(); } /* DB DD */ +OP(dd,e3) { EXSP( ix ); } /* EX (SP),IX */ +OP(dd,e4) { illegal_1(); op_e4(); } /* DB DD */ +OP(dd,e5) { PUSH( ix ); } /* PUSH IX */ +OP(dd,e6) { illegal_1(); op_e6(); } /* DB DD */ +OP(dd,e7) { illegal_1(); op_e7(); } /* DB DD */ + +OP(dd,e8) { illegal_1(); op_e8(); } /* DB DD */ +OP(dd,e9) { PC = IX; } /* JP (IX) */ +OP(dd,ea) { illegal_1(); op_ea(); } /* DB DD */ +OP(dd,eb) { illegal_1(); op_eb(); } /* DB DD */ +OP(dd,ec) { illegal_1(); op_ec(); } /* DB DD */ +OP(dd,ed) { illegal_1(); op_ed(); } /* DB DD */ +OP(dd,ee) { illegal_1(); op_ee(); } /* DB DD */ +OP(dd,ef) { illegal_1(); op_ef(); } /* DB DD */ + +OP(dd,f0) { illegal_1(); op_f0(); } /* DB DD */ +OP(dd,f1) { illegal_1(); op_f1(); } /* DB DD */ +OP(dd,f2) { illegal_1(); op_f2(); } /* DB DD */ +OP(dd,f3) { illegal_1(); op_f3(); } /* DB DD */ +OP(dd,f4) { illegal_1(); op_f4(); } /* DB DD */ +OP(dd,f5) { illegal_1(); op_f5(); } /* DB DD */ +OP(dd,f6) { illegal_1(); op_f6(); } /* DB DD */ +OP(dd,f7) { illegal_1(); op_f7(); } /* DB DD */ + +OP(dd,f8) { illegal_1(); op_f8(); } /* DB DD */ +OP(dd,f9) { SP = IX; } /* LD SP,IX */ +OP(dd,fa) { illegal_1(); op_fa(); } /* DB DD */ +OP(dd,fb) { illegal_1(); op_fb(); } /* DB DD */ +OP(dd,fc) { illegal_1(); op_fc(); } /* DB DD */ +OP(dd,fd) { EXEC(fd,ROP()); } /* **** DD FD xx */ +OP(dd,fe) { illegal_1(); op_fe(); } /* DB DD */ +OP(dd,ff) { illegal_1(); op_ff(); } /* DB DD */ + +/********************************************************** + * IY register related opcodes (FD prefix) + **********************************************************/ +OP(fd,00) { illegal_1(); op_00(); } /* DB FD */ +OP(fd,01) { illegal_1(); op_01(); } /* DB FD */ +OP(fd,02) { illegal_1(); op_02(); } /* DB FD */ +OP(fd,03) { illegal_1(); op_03(); } /* DB FD */ +OP(fd,04) { illegal_1(); op_04(); } /* DB FD */ +OP(fd,05) { illegal_1(); op_05(); } /* DB FD */ +OP(fd,06) { illegal_1(); op_06(); } /* DB FD */ +OP(fd,07) { illegal_1(); op_07(); } /* DB FD */ + +OP(fd,08) { illegal_1(); op_08(); } /* DB FD */ +OP(fd,09) { ADD16(iy,bc); } /* ADD IY,BC */ +OP(fd,0a) { illegal_1(); op_0a(); } /* DB FD */ +OP(fd,0b) { illegal_1(); op_0b(); } /* DB FD */ +OP(fd,0c) { illegal_1(); op_0c(); } /* DB FD */ +OP(fd,0d) { illegal_1(); op_0d(); } /* DB FD */ +OP(fd,0e) { illegal_1(); op_0e(); } /* DB FD */ +OP(fd,0f) { illegal_1(); op_0f(); } /* DB FD */ + +OP(fd,10) { illegal_1(); op_10(); } /* DB FD */ +OP(fd,11) { illegal_1(); op_11(); } /* DB FD */ +OP(fd,12) { illegal_1(); op_12(); } /* DB FD */ +OP(fd,13) { illegal_1(); op_13(); } /* DB FD */ +OP(fd,14) { illegal_1(); op_14(); } /* DB FD */ +OP(fd,15) { illegal_1(); op_15(); } /* DB FD */ +OP(fd,16) { illegal_1(); op_16(); } /* DB FD */ +OP(fd,17) { illegal_1(); op_17(); } /* DB FD */ + +OP(fd,18) { illegal_1(); op_18(); } /* DB FD */ +OP(fd,19) { ADD16(iy,de); } /* ADD IY,DE */ +OP(fd,1a) { illegal_1(); op_1a(); } /* DB FD */ +OP(fd,1b) { illegal_1(); op_1b(); } /* DB FD */ +OP(fd,1c) { illegal_1(); op_1c(); } /* DB FD */ +OP(fd,1d) { illegal_1(); op_1d(); } /* DB FD */ +OP(fd,1e) { illegal_1(); op_1e(); } /* DB FD */ +OP(fd,1f) { illegal_1(); op_1f(); } /* DB FD */ + +OP(fd,20) { illegal_1(); op_20(); } /* DB FD */ +OP(fd,21) { IY = ARG16(); } /* LD IY,w */ +OP(fd,22) { EA = ARG16(); WM16( EA, &Z80.iy ); WZ = EA+1; } /* LD (w),IY */ +OP(fd,23) { IY++; } /* INC IY */ +OP(fd,24) { HY = INC(HY); } /* INC HY */ +OP(fd,25) { HY = DEC(HY); } /* DEC HY */ +OP(fd,26) { HY = ARG(); } /* LD HY,n */ +OP(fd,27) { illegal_1(); op_27(); } /* DB FD */ + +OP(fd,28) { illegal_1(); op_28(); } /* DB FD */ +OP(fd,29) { ADD16(iy,iy); } /* ADD IY,IY */ +OP(fd,2a) { EA = ARG16(); RM16( EA, &Z80.iy ); WZ = EA+1; } /* LD IY,(w) */ +OP(fd,2b) { IY--; } /* DEC IY */ +OP(fd,2c) { LY = INC(LY); } /* INC LY */ +OP(fd,2d) { LY = DEC(LY); } /* DEC LY */ +OP(fd,2e) { LY = ARG(); } /* LD LY,n */ +OP(fd,2f) { illegal_1(); op_2f(); } /* DB FD */ + +OP(fd,30) { illegal_1(); op_30(); } /* DB FD */ +OP(fd,31) { illegal_1(); op_31(); } /* DB FD */ +OP(fd,32) { illegal_1(); op_32(); } /* DB FD */ +OP(fd,33) { illegal_1(); op_33(); } /* DB FD */ +OP(fd,34) { EAY; WM( EA, INC(RM(EA)) ); } /* INC (IY+o) */ +OP(fd,35) { EAY; WM( EA, DEC(RM(EA)) ); } /* DEC (IY+o) */ +OP(fd,36) { EAY; WM( EA, ARG() ); } /* LD (IY+o),n */ +OP(fd,37) { illegal_1(); op_37(); } /* DB FD */ + +OP(fd,38) { illegal_1(); op_38(); } /* DB FD */ +OP(fd,39) { ADD16(iy,sp); } /* ADD IY,SP */ +OP(fd,3a) { illegal_1(); op_3a(); } /* DB FD */ +OP(fd,3b) { illegal_1(); op_3b(); } /* DB FD */ +OP(fd,3c) { illegal_1(); op_3c(); } /* DB FD */ +OP(fd,3d) { illegal_1(); op_3d(); } /* DB FD */ +OP(fd,3e) { illegal_1(); op_3e(); } /* DB FD */ +OP(fd,3f) { illegal_1(); op_3f(); } /* DB FD */ + +OP(fd,40) { illegal_1(); op_40(); } /* DB FD */ +OP(fd,41) { illegal_1(); op_41(); } /* DB FD */ +OP(fd,42) { illegal_1(); op_42(); } /* DB FD */ +OP(fd,43) { illegal_1(); op_43(); } /* DB FD */ +OP(fd,44) { B = HY; } /* LD B,HY */ +OP(fd,45) { B = LY; } /* LD B,LY */ +OP(fd,46) { EAY; B = RM(EA); } /* LD B,(IY+o) */ +OP(fd,47) { illegal_1(); op_47(); } /* DB FD */ + +OP(fd,48) { illegal_1(); op_48(); } /* DB FD */ +OP(fd,49) { illegal_1(); op_49(); } /* DB FD */ +OP(fd,4a) { illegal_1(); op_4a(); } /* DB FD */ +OP(fd,4b) { illegal_1(); op_4b(); } /* DB FD */ +OP(fd,4c) { C = HY; } /* LD C,HY */ +OP(fd,4d) { C = LY; } /* LD C,LY */ +OP(fd,4e) { EAY; C = RM(EA); } /* LD C,(IY+o) */ +OP(fd,4f) { illegal_1(); op_4f(); } /* DB FD */ + +OP(fd,50) { illegal_1(); op_50(); } /* DB FD */ +OP(fd,51) { illegal_1(); op_51(); } /* DB FD */ +OP(fd,52) { illegal_1(); op_52(); } /* DB FD */ +OP(fd,53) { illegal_1(); op_53(); } /* DB FD */ +OP(fd,54) { D = HY; } /* LD D,HY */ +OP(fd,55) { D = LY; } /* LD D,LY */ +OP(fd,56) { EAY; D = RM(EA); } /* LD D,(IY+o) */ +OP(fd,57) { illegal_1(); op_57(); } /* DB FD */ + +OP(fd,58) { illegal_1(); op_58(); } /* DB FD */ +OP(fd,59) { illegal_1(); op_59(); } /* DB FD */ +OP(fd,5a) { illegal_1(); op_5a(); } /* DB FD */ +OP(fd,5b) { illegal_1(); op_5b(); } /* DB FD */ +OP(fd,5c) { E = HY; } /* LD E,HY */ +OP(fd,5d) { E = LY; } /* LD E,LY */ +OP(fd,5e) { EAY; E = RM(EA); } /* LD E,(IY+o) */ +OP(fd,5f) { illegal_1(); op_5f(); } /* DB FD */ + +OP(fd,60) { HY = B; } /* LD HY,B */ +OP(fd,61) { HY = C; } /* LD HY,C */ +OP(fd,62) { HY = D; } /* LD HY,D */ +OP(fd,63) { HY = E; } /* LD HY,E */ +OP(fd,64) { } /* LD HY,HY */ +OP(fd,65) { HY = LY; } /* LD HY,LY */ +OP(fd,66) { EAY; H = RM(EA); } /* LD H,(IY+o) */ +OP(fd,67) { HY = A; } /* LD HY,A */ + +OP(fd,68) { LY = B; } /* LD LY,B */ +OP(fd,69) { LY = C; } /* LD LY,C */ +OP(fd,6a) { LY = D; } /* LD LY,D */ +OP(fd,6b) { LY = E; } /* LD LY,E */ +OP(fd,6c) { LY = HY; } /* LD LY,HY */ +OP(fd,6d) { } /* LD LY,LY */ +OP(fd,6e) { EAY; L = RM(EA); } /* LD L,(IY+o) */ +OP(fd,6f) { LY = A; } /* LD LY,A */ + +OP(fd,70) { EAY; WM( EA, B ); } /* LD (IY+o),B */ +OP(fd,71) { EAY; WM( EA, C ); } /* LD (IY+o),C */ +OP(fd,72) { EAY; WM( EA, D ); } /* LD (IY+o),D */ +OP(fd,73) { EAY; WM( EA, E ); } /* LD (IY+o),E */ +OP(fd,74) { EAY; WM( EA, H ); } /* LD (IY+o),H */ +OP(fd,75) { EAY; WM( EA, L ); } /* LD (IY+o),L */ +OP(fd,76) { illegal_1(); op_76(); } /* DB FD */ +OP(fd,77) { EAY; WM( EA, A ); } /* LD (IY+o),A */ + +OP(fd,78) { illegal_1(); op_78(); } /* DB FD */ +OP(fd,79) { illegal_1(); op_79(); } /* DB FD */ +OP(fd,7a) { illegal_1(); op_7a(); } /* DB FD */ +OP(fd,7b) { illegal_1(); op_7b(); } /* DB FD */ +OP(fd,7c) { A = HY; } /* LD A,HY */ +OP(fd,7d) { A = LY; } /* LD A,LY */ +OP(fd,7e) { EAY; A = RM(EA); } /* LD A,(IY+o) */ +OP(fd,7f) { illegal_1(); op_7f(); } /* DB FD */ + +OP(fd,80) { illegal_1(); op_80(); } /* DB FD */ +OP(fd,81) { illegal_1(); op_81(); } /* DB FD */ +OP(fd,82) { illegal_1(); op_82(); } /* DB FD */ +OP(fd,83) { illegal_1(); op_83(); } /* DB FD */ +OP(fd,84) { ADD(HY); } /* ADD A,HY */ +OP(fd,85) { ADD(LY); } /* ADD A,LY */ +OP(fd,86) { EAY; ADD(RM(EA)); } /* ADD A,(IY+o) */ +OP(fd,87) { illegal_1(); op_87(); } /* DB FD */ + +OP(fd,88) { illegal_1(); op_88(); } /* DB FD */ +OP(fd,89) { illegal_1(); op_89(); } /* DB FD */ +OP(fd,8a) { illegal_1(); op_8a(); } /* DB FD */ +OP(fd,8b) { illegal_1(); op_8b(); } /* DB FD */ +OP(fd,8c) { ADC(HY); } /* ADC A,HY */ +OP(fd,8d) { ADC(LY); } /* ADC A,LY */ +OP(fd,8e) { EAY; ADC(RM(EA)); } /* ADC A,(IY+o) */ +OP(fd,8f) { illegal_1(); op_8f(); } /* DB FD */ + +OP(fd,90) { illegal_1(); op_90(); } /* DB FD */ +OP(fd,91) { illegal_1(); op_91(); } /* DB FD */ +OP(fd,92) { illegal_1(); op_92(); } /* DB FD */ +OP(fd,93) { illegal_1(); op_93(); } /* DB FD */ +OP(fd,94) { SUB(HY); } /* SUB HY */ +OP(fd,95) { SUB(LY); } /* SUB LY */ +OP(fd,96) { EAY; SUB(RM(EA)); } /* SUB (IY+o) */ +OP(fd,97) { illegal_1(); op_97(); } /* DB FD */ + +OP(fd,98) { illegal_1(); op_98(); } /* DB FD */ +OP(fd,99) { illegal_1(); op_99(); } /* DB FD */ +OP(fd,9a) { illegal_1(); op_9a(); } /* DB FD */ +OP(fd,9b) { illegal_1(); op_9b(); } /* DB FD */ +OP(fd,9c) { SBC(HY); } /* SBC A,HY */ +OP(fd,9d) { SBC(LY); } /* SBC A,LY */ +OP(fd,9e) { EAY; SBC(RM(EA)); } /* SBC A,(IY+o) */ +OP(fd,9f) { illegal_1(); op_9f(); } /* DB FD */ + +OP(fd,a0) { illegal_1(); op_a0(); } /* DB FD */ +OP(fd,a1) { illegal_1(); op_a1(); } /* DB FD */ +OP(fd,a2) { illegal_1(); op_a2(); } /* DB FD */ +OP(fd,a3) { illegal_1(); op_a3(); } /* DB FD */ +OP(fd,a4) { AND(HY); } /* AND HY */ +OP(fd,a5) { AND(LY); } /* AND LY */ +OP(fd,a6) { EAY; AND(RM(EA)); } /* AND (IY+o) */ +OP(fd,a7) { illegal_1(); op_a7(); } /* DB FD */ + +OP(fd,a8) { illegal_1(); op_a8(); } /* DB FD */ +OP(fd,a9) { illegal_1(); op_a9(); } /* DB FD */ +OP(fd,aa) { illegal_1(); op_aa(); } /* DB FD */ +OP(fd,ab) { illegal_1(); op_ab(); } /* DB FD */ +OP(fd,ac) { XOR(HY); } /* XOR HY */ +OP(fd,ad) { XOR(LY); } /* XOR LY */ +OP(fd,ae) { EAY; XOR(RM(EA)); } /* XOR (IY+o) */ +OP(fd,af) { illegal_1(); op_af(); } /* DB FD */ + +OP(fd,b0) { illegal_1(); op_b0(); } /* DB FD */ +OP(fd,b1) { illegal_1(); op_b1(); } /* DB FD */ +OP(fd,b2) { illegal_1(); op_b2(); } /* DB FD */ +OP(fd,b3) { illegal_1(); op_b3(); } /* DB FD */ +OP(fd,b4) { OR(HY); } /* OR HY */ +OP(fd,b5) { OR(LY); } /* OR LY */ +OP(fd,b6) { EAY; OR(RM(EA)); } /* OR (IY+o) */ +OP(fd,b7) { illegal_1(); op_b7(); } /* DB FD */ + +OP(fd,b8) { illegal_1(); op_b8(); } /* DB FD */ +OP(fd,b9) { illegal_1(); op_b9(); } /* DB FD */ +OP(fd,ba) { illegal_1(); op_ba(); } /* DB FD */ +OP(fd,bb) { illegal_1(); op_bb(); } /* DB FD */ +OP(fd,bc) { CP(HY); } /* CP HY */ +OP(fd,bd) { CP(LY); } /* CP LY */ +OP(fd,be) { EAY; CP(RM(EA)); } /* CP (IY+o) */ +OP(fd,bf) { illegal_1(); op_bf(); } /* DB FD */ + +OP(fd,c0) { illegal_1(); op_c0(); } /* DB FD */ +OP(fd,c1) { illegal_1(); op_c1(); } /* DB FD */ +OP(fd,c2) { illegal_1(); op_c2(); } /* DB FD */ +OP(fd,c3) { illegal_1(); op_c3(); } /* DB FD */ +OP(fd,c4) { illegal_1(); op_c4(); } /* DB FD */ +OP(fd,c5) { illegal_1(); op_c5(); } /* DB FD */ +OP(fd,c6) { illegal_1(); op_c6(); } /* DB FD */ +OP(fd,c7) { illegal_1(); op_c7(); } /* DB FD */ + +OP(fd,c8) { illegal_1(); op_c8(); } /* DB FD */ +OP(fd,c9) { illegal_1(); op_c9(); } /* DB FD */ +OP(fd,ca) { illegal_1(); op_ca(); } /* DB FD */ +OP(fd,cb) { EAY; EXEC(xycb,ARG()); } /* **** FD CB xx */ +OP(fd,cc) { illegal_1(); op_cc(); } /* DB FD */ +OP(fd,cd) { illegal_1(); op_cd(); } /* DB FD */ +OP(fd,ce) { illegal_1(); op_ce(); } /* DB FD */ +OP(fd,cf) { illegal_1(); op_cf(); } /* DB FD */ + +OP(fd,d0) { illegal_1(); op_d0(); } /* DB FD */ +OP(fd,d1) { illegal_1(); op_d1(); } /* DB FD */ +OP(fd,d2) { illegal_1(); op_d2(); } /* DB FD */ +OP(fd,d3) { illegal_1(); op_d3(); } /* DB FD */ +OP(fd,d4) { illegal_1(); op_d4(); } /* DB FD */ +OP(fd,d5) { illegal_1(); op_d5(); } /* DB FD */ +OP(fd,d6) { illegal_1(); op_d6(); } /* DB FD */ +OP(fd,d7) { illegal_1(); op_d7(); } /* DB FD */ + +OP(fd,d8) { illegal_1(); op_d8(); } /* DB FD */ +OP(fd,d9) { illegal_1(); op_d9(); } /* DB FD */ +OP(fd,da) { illegal_1(); op_da(); } /* DB FD */ +OP(fd,db) { illegal_1(); op_db(); } /* DB FD */ +OP(fd,dc) { illegal_1(); op_dc(); } /* DB FD */ +OP(fd,dd) { EXEC(dd,ROP()); } /* **** FD DD xx */ +OP(fd,de) { illegal_1(); op_de(); } /* DB FD */ +OP(fd,df) { illegal_1(); op_df(); } /* DB FD */ + +OP(fd,e0) { illegal_1(); op_e0(); } /* DB FD */ +OP(fd,e1) { POP( iy ); } /* POP IY */ +OP(fd,e2) { illegal_1(); op_e2(); } /* DB FD */ +OP(fd,e3) { EXSP( iy ); } /* EX (SP),IY */ +OP(fd,e4) { illegal_1(); op_e4(); } /* DB FD */ +OP(fd,e5) { PUSH( iy ); } /* PUSH IY */ +OP(fd,e6) { illegal_1(); op_e6(); } /* DB FD */ +OP(fd,e7) { illegal_1(); op_e7(); } /* DB FD */ + +OP(fd,e8) { illegal_1(); op_e8(); } /* DB FD */ +OP(fd,e9) { PC = IY; } /* JP (IY) */ +OP(fd,ea) { illegal_1(); op_ea(); } /* DB FD */ +OP(fd,eb) { illegal_1(); op_eb(); } /* DB FD */ +OP(fd,ec) { illegal_1(); op_ec(); } /* DB FD */ +OP(fd,ed) { illegal_1(); op_ed(); } /* DB FD */ +OP(fd,ee) { illegal_1(); op_ee(); } /* DB FD */ +OP(fd,ef) { illegal_1(); op_ef(); } /* DB FD */ + +OP(fd,f0) { illegal_1(); op_f0(); } /* DB FD */ +OP(fd,f1) { illegal_1(); op_f1(); } /* DB FD */ +OP(fd,f2) { illegal_1(); op_f2(); } /* DB FD */ +OP(fd,f3) { illegal_1(); op_f3(); } /* DB FD */ +OP(fd,f4) { illegal_1(); op_f4(); } /* DB FD */ +OP(fd,f5) { illegal_1(); op_f5(); } /* DB FD */ +OP(fd,f6) { illegal_1(); op_f6(); } /* DB FD */ +OP(fd,f7) { illegal_1(); op_f7(); } /* DB FD */ + +OP(fd,f8) { illegal_1(); op_f8(); } /* DB FD */ +OP(fd,f9) { SP = IY; } /* LD SP,IY */ +OP(fd,fa) { illegal_1(); op_fa(); } /* DB FD */ +OP(fd,fb) { illegal_1(); op_fb(); } /* DB FD */ +OP(fd,fc) { illegal_1(); op_fc(); } /* DB FD */ +OP(fd,fd) { EXEC(fd,ROP()); } /* **** FD FD xx */ +OP(fd,fe) { illegal_1(); op_fe(); } /* DB FD */ +OP(fd,ff) { illegal_1(); op_ff(); } /* DB FD */ + +OP(illegal,2) +{ +#if VERBOSE +logerror("Z80 #%d ill. opcode $ed $%02x\n", + cpu_getactivecpu(), cpu_readop((PCD-1)&0xffff)); +#endif +} + +/********************************************************** + * special opcodes (ED prefix) + **********************************************************/ +OP(ed,00) { illegal_2(); } /* DB ED */ +OP(ed,01) { illegal_2(); } /* DB ED */ +OP(ed,02) { illegal_2(); } /* DB ED */ +OP(ed,03) { illegal_2(); } /* DB ED */ +OP(ed,04) { illegal_2(); } /* DB ED */ +OP(ed,05) { illegal_2(); } /* DB ED */ +OP(ed,06) { illegal_2(); } /* DB ED */ +OP(ed,07) { illegal_2(); } /* DB ED */ + +OP(ed,08) { illegal_2(); } /* DB ED */ +OP(ed,09) { illegal_2(); } /* DB ED */ +OP(ed,0a) { illegal_2(); } /* DB ED */ +OP(ed,0b) { illegal_2(); } /* DB ED */ +OP(ed,0c) { illegal_2(); } /* DB ED */ +OP(ed,0d) { illegal_2(); } /* DB ED */ +OP(ed,0e) { illegal_2(); } /* DB ED */ +OP(ed,0f) { illegal_2(); } /* DB ED */ + +OP(ed,10) { illegal_2(); } /* DB ED */ +OP(ed,11) { illegal_2(); } /* DB ED */ +OP(ed,12) { illegal_2(); } /* DB ED */ +OP(ed,13) { illegal_2(); } /* DB ED */ +OP(ed,14) { illegal_2(); } /* DB ED */ +OP(ed,15) { illegal_2(); } /* DB ED */ +OP(ed,16) { illegal_2(); } /* DB ED */ +OP(ed,17) { illegal_2(); } /* DB ED */ + +OP(ed,18) { illegal_2(); } /* DB ED */ +OP(ed,19) { illegal_2(); } /* DB ED */ +OP(ed,1a) { illegal_2(); } /* DB ED */ +OP(ed,1b) { illegal_2(); } /* DB ED */ +OP(ed,1c) { illegal_2(); } /* DB ED */ +OP(ed,1d) { illegal_2(); } /* DB ED */ +OP(ed,1e) { illegal_2(); } /* DB ED */ +OP(ed,1f) { illegal_2(); } /* DB ED */ + +OP(ed,20) { illegal_2(); } /* DB ED */ +OP(ed,21) { illegal_2(); } /* DB ED */ +OP(ed,22) { illegal_2(); } /* DB ED */ +OP(ed,23) { illegal_2(); } /* DB ED */ +OP(ed,24) { illegal_2(); } /* DB ED */ +OP(ed,25) { illegal_2(); } /* DB ED */ +OP(ed,26) { illegal_2(); } /* DB ED */ +OP(ed,27) { illegal_2(); } /* DB ED */ + +OP(ed,28) { illegal_2(); } /* DB ED */ +OP(ed,29) { illegal_2(); } /* DB ED */ +OP(ed,2a) { illegal_2(); } /* DB ED */ +OP(ed,2b) { illegal_2(); } /* DB ED */ +OP(ed,2c) { illegal_2(); } /* DB ED */ +OP(ed,2d) { illegal_2(); } /* DB ED */ +OP(ed,2e) { illegal_2(); } /* DB ED */ +OP(ed,2f) { illegal_2(); } /* DB ED */ + +OP(ed,30) { illegal_2(); } /* DB ED */ +OP(ed,31) { illegal_2(); } /* DB ED */ +OP(ed,32) { illegal_2(); } /* DB ED */ +OP(ed,33) { illegal_2(); } /* DB ED */ +OP(ed,34) { illegal_2(); } /* DB ED */ +OP(ed,35) { illegal_2(); } /* DB ED */ +OP(ed,36) { illegal_2(); } /* DB ED */ +OP(ed,37) { illegal_2(); } /* DB ED */ + +OP(ed,38) { illegal_2(); } /* DB ED */ +OP(ed,39) { illegal_2(); } /* DB ED */ +OP(ed,3a) { illegal_2(); } /* DB ED */ +OP(ed,3b) { illegal_2(); } /* DB ED */ +OP(ed,3c) { illegal_2(); } /* DB ED */ +OP(ed,3d) { illegal_2(); } /* DB ED */ +OP(ed,3e) { illegal_2(); } /* DB ED */ +OP(ed,3f) { illegal_2(); } /* DB ED */ + +OP(ed,40) { B = IN(BC); F = (F & CF) | SZP[B]; } /* IN B,(C) */ +OP(ed,41) { OUT(BC, B); } /* OUT (C),B */ +OP(ed,42) { SBC16( bc ); } /* SBC HL,BC */ +OP(ed,43) { EA = ARG16(); WM16( EA, &Z80.bc ); WZ = EA+1; } /* LD (w),BC */ +OP(ed,44) { NEG; } /* NEG */ +OP(ed,45) { RETN; } /* RETN; */ +OP(ed,46) { IM = 0; } /* IM 0 */ +OP(ed,47) { LD_I_A; } /* LD I,A */ + +OP(ed,48) { C = IN(BC); F = (F & CF) | SZP[C]; } /* IN C,(C) */ +OP(ed,49) { OUT(BC, C); } /* OUT (C),C */ +OP(ed,4a) { ADC16( bc ); } /* ADC HL,BC */ +OP(ed,4b) { EA = ARG16(); RM16( EA, &Z80.bc ); WZ = EA+1; } /* LD BC,(w) */ +OP(ed,4c) { NEG; } /* NEG */ +OP(ed,4d) { RETI; } /* RETI */ +OP(ed,4e) { IM = 0; } /* IM 0 */ +OP(ed,4f) { LD_R_A; } /* LD R,A */ + +OP(ed,50) { D = IN(BC); F = (F & CF) | SZP[D]; } /* IN D,(C) */ +OP(ed,51) { OUT(BC, D); } /* OUT (C),D */ +OP(ed,52) { SBC16( de ); } /* SBC HL,DE */ +OP(ed,53) { EA = ARG16(); WM16( EA, &Z80.de ); WZ = EA+1; } /* LD (w),DE */ +OP(ed,54) { NEG; } /* NEG */ +OP(ed,55) { RETN; } /* RETN; */ +OP(ed,56) { IM = 1; } /* IM 1 */ +OP(ed,57) { LD_A_I; } /* LD A,I */ + +OP(ed,58) { E = IN(BC); F = (F & CF) | SZP[E]; } /* IN E,(C) */ +OP(ed,59) { OUT(BC, E); } /* OUT (C),E */ +OP(ed,5a) { ADC16( de ); } /* ADC HL,DE */ +OP(ed,5b) { EA = ARG16(); RM16( EA, &Z80.de ); WZ = EA+1; } /* LD DE,(w) */ +OP(ed,5c) { NEG; } /* NEG */ +OP(ed,5d) { RETI; } /* RETI */ +OP(ed,5e) { IM = 2; } /* IM 2 */ +OP(ed,5f) { LD_A_R; } /* LD A,R */ + +OP(ed,60) { H = IN(BC); F = (F & CF) | SZP[H]; } /* IN H,(C) */ +OP(ed,61) { OUT(BC, H); } /* OUT (C),H */ +OP(ed,62) { SBC16( hl ); } /* SBC HL,HL */ +OP(ed,63) { EA = ARG16(); WM16( EA, &Z80.hl ); WZ = EA+1; } /* LD (w),HL */ +OP(ed,64) { NEG; } /* NEG */ +OP(ed,65) { RETN; } /* RETN; */ +OP(ed,66) { IM = 0; } /* IM 0 */ +OP(ed,67) { RRD; } /* RRD (HL) */ + +OP(ed,68) { L = IN(BC); F = (F & CF) | SZP[L]; } /* IN L,(C) */ +OP(ed,69) { OUT(BC, L); } /* OUT (C),L */ +OP(ed,6a) { ADC16( hl ); } /* ADC HL,HL */ +OP(ed,6b) { EA = ARG16(); RM16( EA, &Z80.hl ); WZ = EA+1; } /* LD HL,(w) */ +OP(ed,6c) { NEG; } /* NEG */ +OP(ed,6d) { RETI; } /* RETI */ +OP(ed,6e) { IM = 0; } /* IM 0 */ +OP(ed,6f) { RLD; } /* RLD (HL) */ + +OP(ed,70) { UINT8 res = IN(BC); F = (F & CF) | SZP[res]; } /* IN 0,(C) */ +OP(ed,71) { OUT(BC, 0); } /* OUT (C),0 */ +OP(ed,72) { SBC16( sp ); } /* SBC HL,SP */ +OP(ed,73) { EA = ARG16(); WM16( EA, &Z80.sp ); WZ = EA+1; } /* LD (w),SP */ +OP(ed,74) { NEG; } /* NEG */ +OP(ed,75) { RETN; } /* RETN; */ +OP(ed,76) { IM = 1; } /* IM 1 */ +OP(ed,77) { illegal_2(); } /* DB ED,77 */ + +OP(ed,78) { A = IN(BC); F = (F & CF) | SZP[A]; WZ = BC+1; } /* IN E,(C) */ +OP(ed,79) { OUT(BC, A); WZ = BC + 1; } /* OUT (C),A */ +OP(ed,7a) { ADC16( sp ); } /* ADC HL,SP */ +OP(ed,7b) { EA = ARG16(); RM16( EA, &Z80.sp ); WZ = EA+1; } /* LD SP,(w) */ +OP(ed,7c) { NEG; } /* NEG */ +OP(ed,7d) { RETI; } /* RETI */ +OP(ed,7e) { IM = 2; } /* IM 2 */ +OP(ed,7f) { illegal_2(); } /* DB ED,7F */ + +OP(ed,80) { illegal_2(); } /* DB ED */ +OP(ed,81) { illegal_2(); } /* DB ED */ +OP(ed,82) { illegal_2(); } /* DB ED */ +OP(ed,83) { illegal_2(); } /* DB ED */ +OP(ed,84) { illegal_2(); } /* DB ED */ +OP(ed,85) { illegal_2(); } /* DB ED */ +OP(ed,86) { illegal_2(); } /* DB ED */ +OP(ed,87) { illegal_2(); } /* DB ED */ + +OP(ed,88) { illegal_2(); } /* DB ED */ +OP(ed,89) { illegal_2(); } /* DB ED */ +OP(ed,8a) { illegal_2(); } /* DB ED */ +OP(ed,8b) { illegal_2(); } /* DB ED */ +OP(ed,8c) { illegal_2(); } /* DB ED */ +OP(ed,8d) { illegal_2(); } /* DB ED */ +OP(ed,8e) { illegal_2(); } /* DB ED */ +OP(ed,8f) { illegal_2(); } /* DB ED */ + +OP(ed,90) { illegal_2(); } /* DB ED */ +OP(ed,91) { illegal_2(); } /* DB ED */ +OP(ed,92) { illegal_2(); } /* DB ED */ +OP(ed,93) { illegal_2(); } /* DB ED */ +OP(ed,94) { illegal_2(); } /* DB ED */ +OP(ed,95) { illegal_2(); } /* DB ED */ +OP(ed,96) { illegal_2(); } /* DB ED */ +OP(ed,97) { illegal_2(); } /* DB ED */ + +OP(ed,98) { illegal_2(); } /* DB ED */ +OP(ed,99) { illegal_2(); } /* DB ED */ +OP(ed,9a) { illegal_2(); } /* DB ED */ +OP(ed,9b) { illegal_2(); } /* DB ED */ +OP(ed,9c) { illegal_2(); } /* DB ED */ +OP(ed,9d) { illegal_2(); } /* DB ED */ +OP(ed,9e) { illegal_2(); } /* DB ED */ +OP(ed,9f) { illegal_2(); } /* DB ED */ + +OP(ed,a0) { LDI; } /* LDI */ +OP(ed,a1) { CPI; } /* CPI */ +OP(ed,a2) { INI; } /* INI */ +OP(ed,a3) { OUTI; } /* OUTI */ +OP(ed,a4) { illegal_2(); } /* DB ED */ +OP(ed,a5) { illegal_2(); } /* DB ED */ +OP(ed,a6) { illegal_2(); } /* DB ED */ +OP(ed,a7) { illegal_2(); } /* DB ED */ + +OP(ed,a8) { LDD; } /* LDD */ +OP(ed,a9) { CPD; } /* CPD */ +OP(ed,aa) { IND; } /* IND */ +OP(ed,ab) { OUTD; } /* OUTD */ +OP(ed,ac) { illegal_2(); } /* DB ED */ +OP(ed,ad) { illegal_2(); } /* DB ED */ +OP(ed,ae) { illegal_2(); } /* DB ED */ +OP(ed,af) { illegal_2(); } /* DB ED */ + +OP(ed,b0) { LDIR; } /* LDIR */ +OP(ed,b1) { CPIR; } /* CPIR */ +OP(ed,b2) { INIR; } /* INIR */ +OP(ed,b3) { OTIR; } /* OTIR */ +OP(ed,b4) { illegal_2(); } /* DB ED */ +OP(ed,b5) { illegal_2(); } /* DB ED */ +OP(ed,b6) { illegal_2(); } /* DB ED */ +OP(ed,b7) { illegal_2(); } /* DB ED */ + +OP(ed,b8) { LDDR; } /* LDDR */ +OP(ed,b9) { CPDR; } /* CPDR */ +OP(ed,ba) { INDR; } /* INDR */ +OP(ed,bb) { OTDR; } /* OTDR */ +OP(ed,bc) { illegal_2(); } /* DB ED */ +OP(ed,bd) { illegal_2(); } /* DB ED */ +OP(ed,be) { illegal_2(); } /* DB ED */ +OP(ed,bf) { illegal_2(); } /* DB ED */ + +OP(ed,c0) { illegal_2(); } /* DB ED */ +OP(ed,c1) { illegal_2(); } /* DB ED */ +OP(ed,c2) { illegal_2(); } /* DB ED */ +OP(ed,c3) { illegal_2(); } /* DB ED */ +OP(ed,c4) { illegal_2(); } /* DB ED */ +OP(ed,c5) { illegal_2(); } /* DB ED */ +OP(ed,c6) { illegal_2(); } /* DB ED */ +OP(ed,c7) { illegal_2(); } /* DB ED */ + +OP(ed,c8) { illegal_2(); } /* DB ED */ +OP(ed,c9) { illegal_2(); } /* DB ED */ +OP(ed,ca) { illegal_2(); } /* DB ED */ +OP(ed,cb) { illegal_2(); } /* DB ED */ +OP(ed,cc) { illegal_2(); } /* DB ED */ +OP(ed,cd) { illegal_2(); } /* DB ED */ +OP(ed,ce) { illegal_2(); } /* DB ED */ +OP(ed,cf) { illegal_2(); } /* DB ED */ + +OP(ed,d0) { illegal_2(); } /* DB ED */ +OP(ed,d1) { illegal_2(); } /* DB ED */ +OP(ed,d2) { illegal_2(); } /* DB ED */ +OP(ed,d3) { illegal_2(); } /* DB ED */ +OP(ed,d4) { illegal_2(); } /* DB ED */ +OP(ed,d5) { illegal_2(); } /* DB ED */ +OP(ed,d6) { illegal_2(); } /* DB ED */ +OP(ed,d7) { illegal_2(); } /* DB ED */ + +OP(ed,d8) { illegal_2(); } /* DB ED */ +OP(ed,d9) { illegal_2(); } /* DB ED */ +OP(ed,da) { illegal_2(); } /* DB ED */ +OP(ed,db) { illegal_2(); } /* DB ED */ +OP(ed,dc) { illegal_2(); } /* DB ED */ +OP(ed,dd) { illegal_2(); } /* DB ED */ +OP(ed,de) { illegal_2(); } /* DB ED */ +OP(ed,df) { illegal_2(); } /* DB ED */ + +OP(ed,e0) { illegal_2(); } /* DB ED */ +OP(ed,e1) { illegal_2(); } /* DB ED */ +OP(ed,e2) { illegal_2(); } /* DB ED */ +OP(ed,e3) { illegal_2(); } /* DB ED */ +OP(ed,e4) { illegal_2(); } /* DB ED */ +OP(ed,e5) { illegal_2(); } /* DB ED */ +OP(ed,e6) { illegal_2(); } /* DB ED */ +OP(ed,e7) { illegal_2(); } /* DB ED */ + +OP(ed,e8) { illegal_2(); } /* DB ED */ +OP(ed,e9) { illegal_2(); } /* DB ED */ +OP(ed,ea) { illegal_2(); } /* DB ED */ +OP(ed,eb) { illegal_2(); } /* DB ED */ +OP(ed,ec) { illegal_2(); } /* DB ED */ +OP(ed,ed) { illegal_2(); } /* DB ED */ +OP(ed,ee) { illegal_2(); } /* DB ED */ +OP(ed,ef) { illegal_2(); } /* DB ED */ + +OP(ed,f0) { illegal_2(); } /* DB ED */ +OP(ed,f1) { illegal_2(); } /* DB ED */ +OP(ed,f2) { illegal_2(); } /* DB ED */ +OP(ed,f3) { illegal_2(); } /* DB ED */ +OP(ed,f4) { illegal_2(); } /* DB ED */ +OP(ed,f5) { illegal_2(); } /* DB ED */ +OP(ed,f6) { illegal_2(); } /* DB ED */ +OP(ed,f7) { illegal_2(); } /* DB ED */ + +OP(ed,f8) { illegal_2(); } /* DB ED */ +OP(ed,f9) { illegal_2(); } /* DB ED */ +OP(ed,fa) { illegal_2(); } /* DB ED */ +OP(ed,fb) { illegal_2(); } /* DB ED */ +OP(ed,fc) { illegal_2(); } /* DB ED */ +OP(ed,fd) { illegal_2(); } /* DB ED */ +OP(ed,fe) { illegal_2(); } /* DB ED */ +OP(ed,ff) { illegal_2(); } /* DB ED */ + + +/********************************************************** + * main opcodes + **********************************************************/ +OP(op,00) { } /* NOP */ +OP(op,01) { BC = ARG16(); } /* LD BC,w */ +OP(op,02) { WM( BC, A ); WZ_L = (BC + 1) & 0xFF; WZ_H = A; } /* LD (BC),A */ +OP(op,03) { BC++; } /* INC BC */ +OP(op,04) { B = INC(B); } /* INC B */ +OP(op,05) { B = DEC(B); } /* DEC B */ +OP(op,06) { B = ARG(); } /* LD B,n */ +OP(op,07) { RLCA; } /* RLCA */ + +OP(op,08) { EX_AF; } /* EX AF,AF' */ +OP(op,09) { ADD16(hl, bc); } /* ADD HL,BC */ +OP(op,0a) { A = RM( BC ); WZ=BC+1; } /* LD A,(BC) */ +OP(op,0b) { BC--; } /* DEC BC */ +OP(op,0c) { C = INC(C); } /* INC C */ +OP(op,0d) { C = DEC(C); } /* DEC C */ +OP(op,0e) { C = ARG(); } /* LD C,n */ +OP(op,0f) { RRCA; } /* RRCA */ + +OP(op,10) { B--; JR_COND( B, 0x10 ); } /* DJNZ o */ +OP(op,11) { DE = ARG16(); } /* LD DE,w */ +OP(op,12) { WM( DE, A ); WZ_L = (DE + 1) & 0xFF; WZ_H = A; } /* LD (DE),A */ +OP(op,13) { DE++; } /* INC DE */ +OP(op,14) { D = INC(D); } /* INC D */ +OP(op,15) { D = DEC(D); } /* DEC D */ +OP(op,16) { D = ARG(); } /* LD D,n */ +OP(op,17) { RLA; } /* RLA */ + +OP(op,18) { JR(); } /* JR o */ +OP(op,19) { ADD16(hl, de); } /* ADD HL,DE */ +OP(op,1a) { A = RM( DE ); WZ=DE+1; } /* LD A,(DE) */ +OP(op,1b) { DE--; } /* DEC DE */ +OP(op,1c) { E = INC(E); } /* INC E */ +OP(op,1d) { E = DEC(E); } /* DEC E */ +OP(op,1e) { E = ARG(); } /* LD E,n */ +OP(op,1f) { RRA; } /* RRA */ + +OP(op,20) { JR_COND( !(F & ZF), 0x20 ); } /* JR NZ,o */ +OP(op,21) { HL = ARG16(); } /* LD HL,w */ +OP(op,22) { EA = ARG16(); WM16( EA, &Z80.hl ); WZ = EA+1; } /* LD (w),HL */ +OP(op,23) { HL++; } /* INC HL */ +OP(op,24) { H = INC(H); } /* INC H */ +OP(op,25) { H = DEC(H); } /* DEC H */ +OP(op,26) { H = ARG(); } /* LD H,n */ +OP(op,27) { DAA; } /* DAA */ + +OP(op,28) { JR_COND( F & ZF, 0x28 ); } /* JR Z,o */ +OP(op,29) { ADD16(hl, hl); } /* ADD HL,HL */ +OP(op,2a) { EA = ARG16(); RM16( EA, &Z80.hl ); WZ = EA+1; } /* LD HL,(w) */ +OP(op,2b) { HL--; } /* DEC HL */ +OP(op,2c) { L = INC(L); } /* INC L */ +OP(op,2d) { L = DEC(L); } /* DEC L */ +OP(op,2e) { L = ARG(); } /* LD L,n */ +OP(op,2f) { A ^= 0xff; F = (F&(SF|ZF|PF|CF))|HF|NF|(A&(YF|XF)); } /* CPL */ + +OP(op,30) { JR_COND( !(F & CF), 0x30 ); } /* JR NC,o */ +OP(op,31) { SP = ARG16(); } /* LD SP,w */ +OP(op,32) { EA = ARG16(); WM( EA, A ); WZ_L=(EA+1)&0xFF;WZ_H=A; } /* LD (w),A */ +OP(op,33) { SP++; } /* INC SP */ +OP(op,34) { WM( HL, INC(RM(HL)) ); } /* INC (HL) */ +OP(op,35) { WM( HL, DEC(RM(HL)) ); } /* DEC (HL) */ +OP(op,36) { WM( HL, ARG() ); } /* LD (HL),n */ +OP(op,37) { F = (F & (SF|ZF|YF|XF|PF)) | CF | (A & (YF|XF)); } /* SCF */ + +OP(op,38) { JR_COND( F & CF, 0x38 ); } /* JR C,o */ +OP(op,39) { ADD16(hl, sp); } /* ADD HL,SP */ +OP(op,3a) { EA = ARG16(); A = RM( EA ); WZ = EA+1; } /* LD A,(w) */ +OP(op,3b) { SP--; } /* DEC SP */ +OP(op,3c) { A = INC(A); } /* INC A */ +OP(op,3d) { A = DEC(A); } /* DEC A */ +OP(op,3e) { A = ARG(); } /* LD A,n */ +OP(op,3f) { F = ((F&(SF|ZF|YF|XF|PF|CF))|((F&CF)<<4)|(A&(YF|XF)))^CF; } /* CCF */ + +OP(op,40) { } /* LD B,B */ +OP(op,41) { B = C; } /* LD B,C */ +OP(op,42) { B = D; } /* LD B,D */ +OP(op,43) { B = E; } /* LD B,E */ +OP(op,44) { B = H; } /* LD B,H */ +OP(op,45) { B = L; } /* LD B,L */ +OP(op,46) { B = RM(HL); } /* LD B,(HL) */ +OP(op,47) { B = A; } /* LD B,A */ + +OP(op,48) { C = B; } /* LD C,B */ +OP(op,49) { } /* LD C,C */ +OP(op,4a) { C = D; } /* LD C,D */ +OP(op,4b) { C = E; } /* LD C,E */ +OP(op,4c) { C = H; } /* LD C,H */ +OP(op,4d) { C = L; } /* LD C,L */ +OP(op,4e) { C = RM(HL); } /* LD C,(HL) */ +OP(op,4f) { C = A; } /* LD C,A */ + +OP(op,50) { D = B; } /* LD D,B */ +OP(op,51) { D = C; } /* LD D,C */ +OP(op,52) { } /* LD D,D */ +OP(op,53) { D = E; } /* LD D,E */ +OP(op,54) { D = H; } /* LD D,H */ +OP(op,55) { D = L; } /* LD D,L */ +OP(op,56) { D = RM(HL); } /* LD D,(HL) */ +OP(op,57) { D = A; } /* LD D,A */ + +OP(op,58) { E = B; } /* LD E,B */ +OP(op,59) { E = C; } /* LD E,C */ +OP(op,5a) { E = D; } /* LD E,D */ +OP(op,5b) { } /* LD E,E */ +OP(op,5c) { E = H; } /* LD E,H */ +OP(op,5d) { E = L; } /* LD E,L */ +OP(op,5e) { E = RM(HL); } /* LD E,(HL) */ +OP(op,5f) { E = A; } /* LD E,A */ + +OP(op,60) { H = B; } /* LD H,B */ +OP(op,61) { H = C; } /* LD H,C */ +OP(op,62) { H = D; } /* LD H,D */ +OP(op,63) { H = E; } /* LD H,E */ +OP(op,64) { } /* LD H,H */ +OP(op,65) { H = L; } /* LD H,L */ +OP(op,66) { H = RM(HL); } /* LD H,(HL) */ +OP(op,67) { H = A; } /* LD H,A */ + +OP(op,68) { L = B; } /* LD L,B */ +OP(op,69) { L = C; } /* LD L,C */ +OP(op,6a) { L = D; } /* LD L,D */ +OP(op,6b) { L = E; } /* LD L,E */ +OP(op,6c) { L = H; } /* LD L,H */ +OP(op,6d) { } /* LD L,L */ +OP(op,6e) { L = RM(HL); } /* LD L,(HL) */ +OP(op,6f) { L = A; } /* LD L,A */ + +OP(op,70) { WM( HL, B ); } /* LD (HL),B */ +OP(op,71) { WM( HL, C ); } /* LD (HL),C */ +OP(op,72) { WM( HL, D ); } /* LD (HL),D */ +OP(op,73) { WM( HL, E ); } /* LD (HL),E */ +OP(op,74) { WM( HL, H ); } /* LD (HL),H */ +OP(op,75) { WM( HL, L ); } /* LD (HL),L */ +OP(op,76) { ENTER_HALT; } /* HALT */ +OP(op,77) { WM( HL, A ); } /* LD (HL),A */ + +OP(op,78) { A = B; } /* LD A,B */ +OP(op,79) { A = C; } /* LD A,C */ +OP(op,7a) { A = D; } /* LD A,D */ +OP(op,7b) { A = E; } /* LD A,E */ +OP(op,7c) { A = H; } /* LD A,H */ +OP(op,7d) { A = L; } /* LD A,L */ +OP(op,7e) { A = RM(HL); } /* LD A,(HL) */ +OP(op,7f) { } /* LD A,A */ + +OP(op,80) { ADD(B); } /* ADD A,B */ +OP(op,81) { ADD(C); } /* ADD A,C */ +OP(op,82) { ADD(D); } /* ADD A,D */ +OP(op,83) { ADD(E); } /* ADD A,E */ +OP(op,84) { ADD(H); } /* ADD A,H */ +OP(op,85) { ADD(L); } /* ADD A,L */ +OP(op,86) { ADD(RM(HL)); } /* ADD A,(HL) */ +OP(op,87) { ADD(A); } /* ADD A,A */ + +OP(op,88) { ADC(B); } /* ADC A,B */ +OP(op,89) { ADC(C); } /* ADC A,C */ +OP(op,8a) { ADC(D); } /* ADC A,D */ +OP(op,8b) { ADC(E); } /* ADC A,E */ +OP(op,8c) { ADC(H); } /* ADC A,H */ +OP(op,8d) { ADC(L); } /* ADC A,L */ +OP(op,8e) { ADC(RM(HL)); } /* ADC A,(HL) */ +OP(op,8f) { ADC(A); } /* ADC A,A */ + +OP(op,90) { SUB(B); } /* SUB B */ +OP(op,91) { SUB(C); } /* SUB C */ +OP(op,92) { SUB(D); } /* SUB D */ +OP(op,93) { SUB(E); } /* SUB E */ +OP(op,94) { SUB(H); } /* SUB H */ +OP(op,95) { SUB(L); } /* SUB L */ +OP(op,96) { SUB(RM(HL)); } /* SUB (HL) */ +OP(op,97) { SUB(A); } /* SUB A */ + +OP(op,98) { SBC(B); } /* SBC A,B */ +OP(op,99) { SBC(C); } /* SBC A,C */ +OP(op,9a) { SBC(D); } /* SBC A,D */ +OP(op,9b) { SBC(E); } /* SBC A,E */ +OP(op,9c) { SBC(H); } /* SBC A,H */ +OP(op,9d) { SBC(L); } /* SBC A,L */ +OP(op,9e) { SBC(RM(HL)); } /* SBC A,(HL) */ +OP(op,9f) { SBC(A); } /* SBC A,A */ + +OP(op,a0) { AND(B); } /* AND B */ +OP(op,a1) { AND(C); } /* AND C */ +OP(op,a2) { AND(D); } /* AND D */ +OP(op,a3) { AND(E); } /* AND E */ +OP(op,a4) { AND(H); } /* AND H */ +OP(op,a5) { AND(L); } /* AND L */ +OP(op,a6) { AND(RM(HL)); } /* AND (HL) */ +OP(op,a7) { AND(A); } /* AND A */ + +OP(op,a8) { XOR(B); } /* XOR B */ +OP(op,a9) { XOR(C); } /* XOR C */ +OP(op,aa) { XOR(D); } /* XOR D */ +OP(op,ab) { XOR(E); } /* XOR E */ +OP(op,ac) { XOR(H); } /* XOR H */ +OP(op,ad) { XOR(L); } /* XOR L */ +OP(op,ae) { XOR(RM(HL)); } /* XOR (HL) */ +OP(op,af) { XOR(A); } /* XOR A */ + +OP(op,b0) { OR(B); } /* OR B */ +OP(op,b1) { OR(C); } /* OR C */ +OP(op,b2) { OR(D); } /* OR D */ +OP(op,b3) { OR(E); } /* OR E */ +OP(op,b4) { OR(H); } /* OR H */ +OP(op,b5) { OR(L); } /* OR L */ +OP(op,b6) { OR(RM(HL)); } /* OR (HL) */ +OP(op,b7) { OR(A); } /* OR A */ + +OP(op,b8) { CP(B); } /* CP B */ +OP(op,b9) { CP(C); } /* CP C */ +OP(op,ba) { CP(D); } /* CP D */ +OP(op,bb) { CP(E); } /* CP E */ +OP(op,bc) { CP(H); } /* CP H */ +OP(op,bd) { CP(L); } /* CP L */ +OP(op,be) { CP(RM(HL)); } /* CP (HL) */ +OP(op,bf) { CP(A); } /* CP A */ + +OP(op,c0) { RET_COND( !(F & ZF), 0xc0 ); } /* RET NZ */ +OP(op,c1) { POP( bc ); } /* POP BC */ +OP(op,c2) { JP_COND( !(F & ZF) ); } /* JP NZ,a */ +OP(op,c3) { JP; } /* JP a */ +OP(op,c4) { CALL_COND( !(F & ZF), 0xc4 ); } /* CALL NZ,a */ +OP(op,c5) { PUSH( bc ); } /* PUSH BC */ +OP(op,c6) { ADD(ARG()); } /* ADD A,n */ +OP(op,c7) { RST(0x00); } /* RST 0 */ + +OP(op,c8) { RET_COND( F & ZF, 0xc8 ); } /* RET Z */ +OP(op,c9) { POP( pc ); WZ=PCD; } /* RET */ +OP(op,ca) { JP_COND( F & ZF ); } /* JP Z,a */ +OP(op,cb) { R++; EXEC(cb,ROP()); } /* **** CB xx */ +OP(op,cc) { CALL_COND( F & ZF, 0xcc ); } /* CALL Z,a */ +OP(op,cd) { CALL(); } /* CALL a */ +OP(op,ce) { ADC(ARG()); } /* ADC A,n */ +OP(op,cf) { RST(0x08); } /* RST 1 */ + +OP(op,d0) { RET_COND( !(F & CF), 0xd0 ); } /* RET NC */ +OP(op,d1) { POP( de ); } /* POP DE */ +OP(op,d2) { JP_COND( !(F & CF) ); } /* JP NC,a */ +OP(op,d3) { unsigned n = ARG() | (A << 8); OUT( n, A ); WZ_L = ((n & 0xff) + 1) & 0xff; WZ_H = A; } /* OUT (n),A */ +OP(op,d4) { CALL_COND( !(F & CF), 0xd4 ); } /* CALL NC,a */ +OP(op,d5) { PUSH( de ); } /* PUSH DE */ +OP(op,d6) { SUB(ARG()); } /* SUB n */ +OP(op,d7) { RST(0x10); } /* RST 2 */ + +OP(op,d8) { RET_COND( F & CF, 0xd8 ); } /* RET C */ +OP(op,d9) { EXX; } /* EXX */ +OP(op,da) { JP_COND( F & CF ); } /* JP C,a */ +OP(op,db) { unsigned n = ARG() | (A << 8); A = IN( n ); WZ = n + 1; } /* IN A,(n) */ +OP(op,dc) { CALL_COND( F & CF, 0xdc ); } /* CALL C,a */ +OP(op,dd) { R++; EXEC(dd,ROP()); } /* **** DD xx */ +OP(op,de) { SBC(ARG()); } /* SBC A,n */ +OP(op,df) { RST(0x18); } /* RST 3 */ + +OP(op,e0) { RET_COND( !(F & PF), 0xe0 ); } /* RET PO */ +OP(op,e1) { POP( hl ); } /* POP HL */ +OP(op,e2) { JP_COND( !(F & PF) ); } /* JP PO,a */ +OP(op,e3) { EXSP( hl ); } /* EX HL,(SP) */ +OP(op,e4) { CALL_COND( !(F & PF), 0xe4 ); } /* CALL PO,a */ +OP(op,e5) { PUSH( hl ); } /* PUSH HL */ +OP(op,e6) { AND(ARG()); } /* AND n */ +OP(op,e7) { RST(0x20); } /* RST 4 */ + +OP(op,e8) { RET_COND( F & PF, 0xe8 ); } /* RET PE */ +OP(op,e9) { PC = HL; } /* JP (HL) */ +OP(op,ea) { JP_COND( F & PF ); } /* JP PE,a */ +OP(op,eb) { EX_DE_HL; } /* EX DE,HL */ +OP(op,ec) { CALL_COND( F & PF, 0xec ); } /* CALL PE,a */ +OP(op,ed) { R++; EXEC(ed,ROP()); } /* **** ED xx */ +OP(op,ee) { XOR(ARG()); } /* XOR n */ +OP(op,ef) { RST(0x28); } /* RST 5 */ + +OP(op,f0) { RET_COND( !(F & SF), 0xf0 ); } /* RET P */ +OP(op,f1) { POP( af ); } /* POP AF */ +OP(op,f2) { JP_COND( !(F & SF) ); } /* JP P,a */ +OP(op,f3) { IFF1 = IFF2 = 0; } /* DI */ +OP(op,f4) { CALL_COND( !(F & SF), 0xf4 ); } /* CALL P,a */ +OP(op,f5) { PUSH( af ); } /* PUSH AF */ +OP(op,f6) { OR(ARG()); } /* OR n */ +OP(op,f7) { RST(0x30); } /* RST 6 */ + +OP(op,f8) { RET_COND( F & SF, 0xf8 ); } /* RET M */ +OP(op,f9) { SP = HL; } /* LD SP,HL */ +OP(op,fa) { JP_COND(F & SF); } /* JP M,a */ +OP(op,fb) { EI; } /* EI */ +OP(op,fc) { CALL_COND( F & SF, 0xfc ); } /* CALL M,a */ +OP(op,fd) { R++; EXEC(fd,ROP()); } /* **** FD xx */ +OP(op,fe) { CP(ARG()); } /* CP n */ +OP(op,ff) { RST(0x38); } /* RST 7 */ + + +static void take_interrupt(void) +{ + /* Check if processor was halted */ + LEAVE_HALT; + + /* Clear both interrupt flip flops */ + IFF1 = IFF2 = 0; + + LOG(("Z80 #%d single int. irq_vector $%02x\n", cpu_getactivecpu(), irq_vector)); + + /* Interrupt mode 1. RST 38h */ + if( IM == 1 ) + { + LOG(("Z80 #%d IM1 $0038\n",cpu_getactivecpu() )); + PUSH( pc ); + PCD = 0x0038; + /* RST $38 + 'interrupt latency' cycles */ + Z80.cycles += cc[Z80_TABLE_op][0xff] + cc[Z80_TABLE_ex][0xff]; + } + else + { + /* call back the cpu interface to retrieve the vector */ + int irq_vector = (*Z80.irq_callback)(0); + + /* Interrupt mode 2. Call [Z80.i:databyte] */ + if( IM == 2 ) + { + irq_vector = (irq_vector & 0xff) | (I << 8); + PUSH( pc ); + RM16( irq_vector, &Z80.pc ); + LOG(("Z80 #%d IM2 [$%04x] = $%04x\n",cpu_getactivecpu() , irq_vector, PCD)); + /* CALL $xxxx + 'interrupt latency' cycles */ + Z80.cycles += cc[Z80_TABLE_op][0xcd] + cc[Z80_TABLE_ex][0xff]; + } + else + { + /* Interrupt mode 0. We check for CALL and JP instructions, */ + /* if neither of these were found we assume a 1 byte opcode */ + /* was placed on the databus */ + LOG(("Z80 #%d IM0 $%04x\n",cpu_getactivecpu() , irq_vector)); + switch (irq_vector & 0xff0000) + { + case 0xcd0000: /* call */ + PUSH( pc ); + PCD = irq_vector & 0xffff; + /* CALL $xxxx + 'interrupt latency' cycles */ + Z80.cycles += cc[Z80_TABLE_op][0xcd] + cc[Z80_TABLE_ex][0xff]; + break; + case 0xc30000: /* jump */ + PCD = irq_vector & 0xffff; + /* JP $xxxx + 2 cycles */ + Z80.cycles += cc[Z80_TABLE_op][0xc3] + cc[Z80_TABLE_ex][0xff]; + break; + default: /* rst (or other opcodes?) */ + PUSH( pc ); + PCD = irq_vector & 0x0038; + /* RST $xx + 2 cycles */ + Z80.cycles += cc[Z80_TABLE_op][0xff] + cc[Z80_TABLE_ex][0xff]; + break; + } + } + } + WZ=PCD; +} + +/**************************************************************************** + * Processor initialization + ****************************************************************************/ +void z80_init(const void *config, int (*irqcallback)(int)) +{ + int i, p; + + int oldval, newval, val; + UINT8 *padd = &SZHVC_add[ 0*256]; + UINT8 *padc = &SZHVC_add[256*256]; + UINT8 *psub = &SZHVC_sub[ 0*256]; + UINT8 *psbc = &SZHVC_sub[256*256]; + for (oldval = 0; oldval < 256; oldval++) + { + for (newval = 0; newval < 256; newval++) + { + /* add or adc w/o carry set */ + val = newval - oldval; + *padd = (newval) ? ((newval & 0x80) ? SF : 0) : ZF; + *padd |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ + if( (newval & 0x0f) < (oldval & 0x0f) ) *padd |= HF; + if( newval < oldval ) *padd |= CF; + if( (val^oldval^0x80) & (val^newval) & 0x80 ) *padd |= VF; + padd++; + + /* adc with carry set */ + val = newval - oldval - 1; + *padc = (newval) ? ((newval & 0x80) ? SF : 0) : ZF; + *padc |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ + if( (newval & 0x0f) <= (oldval & 0x0f) ) *padc |= HF; + if( newval <= oldval ) *padc |= CF; + if( (val^oldval^0x80) & (val^newval) & 0x80 ) *padc |= VF; + padc++; + + /* cp, sub or sbc w/o carry set */ + val = oldval - newval; + *psub = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF); + *psub |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ + if( (newval & 0x0f) > (oldval & 0x0f) ) *psub |= HF; + if( newval > oldval ) *psub |= CF; + if( (val^oldval) & (oldval^newval) & 0x80 ) *psub |= VF; + psub++; + + /* sbc with carry set */ + val = oldval - newval - 1; + *psbc = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF); + *psbc |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ + if( (newval & 0x0f) >= (oldval & 0x0f) ) *psbc |= HF; + if( newval >= oldval ) *psbc |= CF; + if( (val^oldval) & (oldval^newval) & 0x80 ) *psbc |= VF; + psbc++; + } + } + + for (i = 0; i < 256; i++) + { + p = 0; + if( i&0x01 ) ++p; + if( i&0x02 ) ++p; + if( i&0x04 ) ++p; + if( i&0x08 ) ++p; + if( i&0x10 ) ++p; + if( i&0x20 ) ++p; + if( i&0x40 ) ++p; + if( i&0x80 ) ++p; + SZ[i] = i ? i & SF : ZF; + SZ[i] |= (i & (YF | XF)); /* undocumented flag bits 5+3 */ + SZ_BIT[i] = i ? i & SF : ZF | PF; + SZ_BIT[i] |= (i & (YF | XF)); /* undocumented flag bits 5+3 */ + SZP[i] = SZ[i] | ((p & 1) ? 0 : PF); + SZHV_inc[i] = SZ[i]; + if( i == 0x80 ) SZHV_inc[i] |= VF; + if( (i & 0x0f) == 0x00 ) SZHV_inc[i] |= HF; + SZHV_dec[i] = SZ[i] | NF; + if( i == 0x7f ) SZHV_dec[i] |= VF; + if( (i & 0x0f) == 0x0f ) SZHV_dec[i] |= HF; + } + + /* Initialize Z80 */ + memset(&Z80, 0, sizeof(Z80)); + Z80.daisy = config; + Z80.irq_callback = irqcallback; + + /* Clear registers values (NB: should be random on real hardware ?) */ + AF = BC = DE = HL = SP = IX = IY =0; + F = ZF; /* Zero flag is set */ + + /* setup cycle tables */ + cc[Z80_TABLE_op] = cc_op; + cc[Z80_TABLE_cb] = cc_cb; + cc[Z80_TABLE_ed] = cc_ed; + cc[Z80_TABLE_xy] = cc_xy; + cc[Z80_TABLE_xycb] = cc_xycb; + cc[Z80_TABLE_ex] = cc_ex; +} + +/**************************************************************************** + * Do a reset + ****************************************************************************/ +void z80_reset(void) +{ + PC = 0x0000; + I = 0; + R = 0; + R2 = 0; + IM = 0; + IFF1 = IFF2 = 0; + HALT = 0; + + Z80.after_ei = FALSE; + + WZ=PCD; +} + +/**************************************************************************** + * Run until given cycle count + ****************************************************************************/ +void z80_run(unsigned int cycles) +{ + while( Z80.cycles < cycles ) + { + /* check for IRQs before each instruction */ + if (Z80.irq_state && IFF1 && !Z80.after_ei) + { + take_interrupt(); + if (Z80.cycles >= cycles) return; + } + + Z80.after_ei = FALSE; + R++; + EXEC_INLINE(op,ROP()); + } +} + +/**************************************************************************** + * Get all registers in given buffer + ****************************************************************************/ +void z80_get_context (void *dst) +{ + if( dst ) + *(Z80_Regs*)dst = Z80; +} + +/**************************************************************************** + * Set all registers to given values + ****************************************************************************/ +void z80_set_context (void *src) +{ + if( src ) + Z80 = *(Z80_Regs*)src; +} + +/**************************************************************************** + * Set IRQ lines + ****************************************************************************/ +void z80_set_irq_line(unsigned int state) +{ + Z80.irq_state = state; +} + +void z80_set_nmi_line(unsigned int state) +{ + /* mark an NMI pending on the rising edge */ + if (Z80.nmi_state == CLEAR_LINE && state != CLEAR_LINE) + { + LOG(("Z80 #%d take NMI\n", cpu_getactivecpu())); + LEAVE_HALT; /* Check if processor was halted */ + + IFF1 = 0; + PUSH( pc ); + PCD = 0x0066; + WZ=PCD; + + Z80.cycles += 11*15; + } + + Z80.nmi_state = state; +} + diff --git a/genplus-gx/core/z80/z80.h b/genplus-gx/core/z80/z80.h new file mode 100644 index 0000000000..d505775162 --- /dev/null +++ b/genplus-gx/core/z80/z80.h @@ -0,0 +1,71 @@ +#ifndef Z80_H_ +#define Z80_H_ + +#include "osd_cpu.h" + +enum +{ + /* line states */ + CLEAR_LINE = 0, /* clear (a fired, held or pulsed) line */ + ASSERT_LINE, /* assert an interrupt immediately */ + HOLD_LINE, /* hold interrupt line until acknowledged */ + PULSE_LINE /* pulse interrupt line for one instruction */ +}; + +enum { + Z80_PC, Z80_SP, + Z80_A, Z80_B, Z80_C, Z80_D, Z80_E, Z80_H, Z80_L, + Z80_AF, Z80_BC, Z80_DE, Z80_HL, + Z80_IX, Z80_IY, Z80_AF2, Z80_BC2, Z80_DE2, Z80_HL2, + Z80_R, Z80_I, Z80_IM, Z80_IFF1, Z80_IFF2, Z80_HALT, + Z80_DC0, Z80_DC1, Z80_DC2, Z80_DC3, Z80_WZ +}; + +enum { + Z80_TABLE_op, + Z80_TABLE_cb, + Z80_TABLE_ed, + Z80_TABLE_xy, + Z80_TABLE_xycb, + Z80_TABLE_ex /* cycles counts for taken jr/jp/call and interrupt latency (rst opcodes) */ +}; + +/****************************************************************************/ +/* The Z80 registers. HALT is set to 1 when the CPU is halted, the refresh */ +/* register is calculated as follows: refresh=(Z80.r&127)|(Z80.r2&128) */ +/****************************************************************************/ +typedef struct +{ + PAIR pc,sp,af,bc,de,hl,ix,iy,wz; + PAIR af2,bc2,de2,hl2; + UINT8 r,r2,iff1,iff2,halt,im,i; + UINT8 nmi_state; /* nmi line state */ + UINT8 nmi_pending; /* nmi pending */ + UINT8 irq_state; /* irq line state */ + UINT8 after_ei; /* are we in the EI shadow? */ + UINT32 cycles; /* master clock cycles global counter */ + const struct z80_irq_daisy_chain *daisy; + int (*irq_callback)(int irqline); +} Z80_Regs; + + +extern Z80_Regs Z80; + +extern unsigned char *z80_readmap[64]; +extern unsigned char *z80_writemap[64]; + +extern void (*z80_writemem)(unsigned int address, unsigned char data); +extern unsigned char (*z80_readmem)(unsigned int address); +extern void (*z80_writeport)(unsigned int port, unsigned char data); +extern unsigned char (*z80_readport)(unsigned int port); + +extern void z80_init(const void *config, int (*irqcallback)(int)); +extern void z80_reset (void); +extern void z80_run(unsigned int cycles); +extern void z80_get_context (void *dst); +extern void z80_set_context (void *src); +extern void z80_set_irq_line(unsigned int state); +extern void z80_set_nmi_line(unsigned int state); + +#endif + diff --git a/genplus-gx/gx/config.c b/genplus-gx/gx/config.c new file mode 100644 index 0000000000..d13b15bbb5 --- /dev/null +++ b/genplus-gx/gx/config.c @@ -0,0 +1,272 @@ +/**************************************************************************** + * config.c + * + * Genesis Plus GX configuration file support + * + * Copyright Eke-Eke (2007-2013) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "gui.h" +#include "file_load.h" + +static int config_load(void) +{ + /* open configuration file */ + char fname[MAXPATHLEN]; + sprintf (fname, "%s/config.ini", DEFAULT_PATH); + FILE *fp = fopen(fname, "rb"); + if (fp) + { + /* check file size */ + fseek(fp, 0, SEEK_END); + if (ftell(fp) != sizeof(config)) + { + fclose(fp); + return 0; + } + + /* check version */ + char version[16]; + fseek(fp, 0, SEEK_SET); + fread(version, 16, 1, fp); + if (memcmp(version,CONFIG_VERSION,16)) + { + fclose(fp); + return 0; + } + + /* read file */ + fseek(fp, 0, SEEK_SET); + fread(&config, sizeof(config), 1, fp); + fclose(fp); + return 1; + } + return 0; +} + +void config_save(void) +{ + /* open configuration file */ + char fname[MAXPATHLEN]; + sprintf (fname, "%s/config.ini", DEFAULT_PATH); + FILE *fp = fopen(fname, "wb"); + if (fp) + { + /* write file */ + fwrite(&config, sizeof(config), 1, fp); + fclose(fp); + } +} + +void config_default(void) +{ + /* version TAG */ + strncpy(config.version,CONFIG_VERSION,16); + + /* sound options */ + config.psg_preamp = 150; + config.fm_preamp = 100; + config.hq_fm = 1; + config.psgBoostNoise = 1; + config.filter = 1; + config.lp_range = 0x9999; /* 0.6 in 16.16 fixed point */ + config.low_freq = 880; + config.high_freq = 5000; + config.lg = 1.0; + config.mg = 1.0; + config.hg = 1.0; + config.dac_bits = 14; + config.ym2413 = 2; /* AUTO */ + config.mono = 0; + + /* system options */ + config.system = 0; /* AUTO */ + config.region_detect = 0; /* AUTO */ + config.vdp_mode = 0; /* AUTO */ + config.master_clock = 0; /* AUTO */ + config.force_dtack = 0; + config.addr_error = 1; + config.bios = 0; + config.lock_on = 0; + config.hot_swap = 0; + + /* video options */ + config.xshift = 0; + config.yshift = 0; + config.xscale = 0; + config.yscale = 0; + config.aspect = 1; + config.overscan = 3; /* FULL */ + config.gg_extra = 0; + config.ntsc = 0; + config.vsync = 1; /* AUTO */ + config.bilinear = 0; + config.vfilter = 1; + + if (VIDEO_HaveComponentCable()) + { + config.render = 2; + } + else + { + config.render = 0; + } + + switch (vmode->viTVMode >> 2) + { + case VI_PAL: + config.tv_mode = 1; /* 50hz only */ + break; + + case VI_EURGB60: + config.tv_mode = 2; /* 50/60hz */ + break; + + default: + config.tv_mode = 0; /* 60hz only */ + break; + } + +#ifdef HW_RVL + config.trap = 0; + config.gamma = VI_GM_1_0 / 10.0; +#endif + + /* controllers options */ + config.gun_cursor[0] = 1; + config.gun_cursor[1] = 1; + config.invert_mouse = 0; + + /* on-screen options */ + config.cd_leds = 0; + config.fps = 0; + + /* menu options */ + config.autoload = 0; + config.autocheat = 0; +#ifdef HW_RVL + config.s_auto = 1; +#else + config.s_auto = 0; + config.v_prog = 1; +#endif + config.s_default = 1; + config.s_device = 0; + config.l_device = 0; + config.bg_overlay = 0; + config.screen_w = 658; + config.bgm_volume = 100.0; + config.sfx_volume = 100.0; + + /* default ROM directories */ +#ifdef HW_RVL + sprintf (config.lastdir[0][TYPE_SD], "sd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[1][TYPE_SD], "sd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[2][TYPE_SD], "sd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[3][TYPE_SD], "sd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[4][TYPE_SD], "sd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[0][TYPE_USB], "usb:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[1][TYPE_USB], "usb:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[2][TYPE_USB], "usb:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[3][TYPE_USB], "usb:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[4][TYPE_USB], "usb:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[0][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[1][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[2][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[3][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[4][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH); +#else + sprintf (config.lastdir[0][TYPE_SD], "%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[1][TYPE_SD], "%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[2][TYPE_SD], "%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[3][TYPE_SD], "%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[4][TYPE_SD], "%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[0][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[1][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[2][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[3][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH); + sprintf (config.lastdir[4][TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH); +#endif + + /* try to restore user config */ + int loaded = config_load(); + +#ifndef HW_RVL + /* check if component cable was detected */ + if (VIDEO_HaveComponentCable()) + { + /* when component cable is detected, libogc automatically enables progressive mode */ + /* as preferred video mode but it could still be used on TV not supporting 480p/576p */ + PAD_ScanPads(); + + /* detect progressive mode switch requests */ + if (PAD_ButtonsHeld(0) & PAD_BUTTON_B) + { + /* swap progressive mode enable flag */ + config.v_prog ^= 1; + + /* play some sound to inform user */ + ASND_Pause(0); + int voice = ASND_GetFirstUnusedVoice(); + ASND_SetVoice(voice,VOICE_MONO_16BIT,44100,0,(u8 *)intro_pcm,intro_pcm_size,200,200,NULL); + sleep (2); + ASND_Pause(1); + } + + /* check if progressive mode should be disabled */ + if (!config.v_prog) + { + /* switch menu video mode to interlaced */ + vmode->viTVMode = (vmode->viTVMode & ~3) | VI_INTERLACE; + VIDEO_Configure (vmode); + VIDEO_Flush(); + VIDEO_WaitVSync(); + VIDEO_WaitVSync(); + } + } +#endif + + /* inform user if default config is used */ + if (!loaded) + { + GUI_WaitPrompt("Warning","Default Settings restored"); + gx_input_SetDefault(); + } + + /* default emulated inputs */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = (config.input[1].device != -1) ? SYSTEM_MD_GAMEPAD : NO_SYSTEM; + input_init(); +} diff --git a/genplus-gx/gx/config.h b/genplus-gx/gx/config.h new file mode 100644 index 0000000000..59b773e1ff --- /dev/null +++ b/genplus-gx/gx/config.h @@ -0,0 +1,125 @@ +/**************************************************************************** + * config.c + * + * Genesis Plus GX configuration file support + * + * Copyright Eke-Eke (2007-2013) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#define CONFIG_VERSION "GENPLUS-GX 1.7.5" + +/**************************************************************************** + * Config Option + * + ****************************************************************************/ +typedef struct +{ + char version[16]; + uint8 hq_fm; + uint8 filter; + uint8 psgBoostNoise; + uint8 dac_bits; + uint8 ym2413; + uint8 mono; + int16 psg_preamp; + int16 fm_preamp; + uint32 lp_range; + int16 low_freq; + int16 high_freq; + int16 lg; + int16 mg; + int16 hg; + uint8 system; + uint8 region_detect; + uint8 master_clock; + uint8 vdp_mode; + uint8 force_dtack; + uint8 addr_error; + uint8 bios; + uint8 lock_on; + uint8 hot_swap; + uint8 invert_mouse; + uint8 gun_cursor[2]; + uint8 overscan; + uint8 gg_extra; + uint8 ntsc; + uint8 vsync; + uint8 render; + uint8 tv_mode; + uint8 bilinear; + uint8 vfilter; + uint8 aspect; + int16 xshift; + int16 yshift; + int16 xscale; + int16 yscale; +#ifdef HW_RVL + uint32 trap; + float gamma; +#else + uint8 v_prog; +#endif + t_input_config input[MAX_INPUTS]; + uint16 pad_keymap[4][MAX_KEYS+1]; +#ifdef HW_RVL + uint32 wpad_keymap[4*3][MAX_KEYS]; +#endif + uint8 autoload; + uint8 autocheat; + uint8 s_auto; + uint8 s_default; + uint8 s_device; + uint8 l_device; + uint8 bg_overlay; + uint8 cd_leds; + uint8 fps; + int16 screen_w; + float bgm_volume; + float sfx_volume; + char lastdir[FILETYPE_MAX][TYPE_RECENT][MAXPATHLEN]; +} t_config; + +/* Global data */ +t_config config; + + +extern void config_save(void); +extern void config_default(void); + + +#endif /* _CONFIG_H_ */ + diff --git a/genplus-gx/gx/fileio/file_load.c b/genplus-gx/gx/fileio/file_load.c new file mode 100644 index 0000000000..e896c4e312 --- /dev/null +++ b/genplus-gx/gx/fileio/file_load.c @@ -0,0 +1,464 @@ +/* + * file_load.c + * + * ROM File loading support + * + * Copyright Eke-Eke (2008-2012) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "file_load.h" +#include "gui.h" +#include "history.h" +#include "filesel.h" +#include "file_slot.h" + +#include +#ifdef HW_RVL +#include +#else +#include +#endif + +char rom_filename[256]; + +/* device root directories */ +#ifdef HW_RVL +static const char rootdir[TYPE_RECENT][10] = {"sd:/","usb:/","dvd:/"}; +#else +static const char rootdir[TYPE_RECENT][10] = {"/","dvd:/"}; +#endif + +/* DVD interface */ +#ifdef HW_RVL +static const DISC_INTERFACE* dvd = &__io_wiidvd; +#else +static const DISC_INTERFACE* dvd = &__io_gcdvd; +#endif + +/* current directory */ +static char *fileDir; + +/* current device */ +static int deviceType = -1; + +/* current file type */ +static int fileType = -1; + +/* DVD status flag */ +static u8 dvd_mounted = 0; + +/*************************************************************************** + * MountDVD + * + * return 0 on error, 1 on success + ***************************************************************************/ +static int MountDVD(void) +{ + GUI_MsgBoxOpen("Information", "Mounting DVD ...",1); + + /* initialize DVD interface if needed */ +#ifdef HW_RVL + DI_Init(); +#else + DVD_Init(); +#endif + + /* check if DVD is already mounted */ + if (dvd_mounted) + { + /* unmount DVD */ + ISO9660_Unmount("dvd:"); + dvd_mounted = 0; + } + + /* check if disc is found */ + if(!dvd->isInserted()) + { + GUI_WaitPrompt("Error","No Disc inserted !"); + return 0; + } + + /* mount DVD */ + if(!ISO9660_Mount("dvd",dvd)) + { + GUI_WaitPrompt("Error","Disc can not be read !"); + return 0; + } + + /* DVD is mounted */ + dvd_mounted = 1; + + GUI_MsgBoxClose(); + return 1; +} + +/*************************************************************************** + * FileSortCallback (thanks to Marty Disibio) + * + * Quick sort callback to sort file entries with the following order: + * . + * .. + * + * + ***************************************************************************/ +static int FileSortCallback(const void *f1, const void *f2) +{ + /* Special case for implicit directories */ + if(((FILEENTRIES *)f1)->filename[0] == '.' || ((FILEENTRIES *)f2)->filename[0] == '.') + { + if(strcmp(((FILEENTRIES *)f1)->filename, ".") == 0) { return -1; } + if(strcmp(((FILEENTRIES *)f2)->filename, ".") == 0) { return 1; } + if(strcmp(((FILEENTRIES *)f1)->filename, "..") == 0) { return -1; } + if(strcmp(((FILEENTRIES *)f2)->filename, "..") == 0) { return 1; } + } + + /* If one is a file and one is a directory the directory is first. */ + if(((FILEENTRIES *)f1)->flags && !((FILEENTRIES *)f2)->flags) return -1; + if(!((FILEENTRIES *)f1)->flags && ((FILEENTRIES *)f2)->flags) return 1; + + return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename); +} + +/*************************************************************************** + * UpdateDirectory + * + * Update current browser directory + * return zero if going up while in root + * when going up, return previous dir name + ***************************************************************************/ +int UpdateDirectory(bool go_up, char *dirname) +{ + /* go up to parent directory */ + if (go_up) + { + /* special case */ + if (deviceType == TYPE_RECENT) return 0; + + /* check if we already are at root directory */ + if (!strcmp(rootdir[deviceType], (const char *)fileDir)) return 0; + + int size=0; + char temp[MAXPATHLEN]; + + /* determine last folder name length */ + strcpy(temp, fileDir); + char *test= strtok(temp,"/"); + while (test != NULL) + { + size = strlen(test); + strncpy(dirname,test,size); + dirname[size] = 0; + test = strtok(NULL,"/"); + } + + /* remove last folder from path */ + size = strlen(fileDir) - size; + fileDir[size - 1] = 0; + } + else + { + /* by default, simply append folder name */ + sprintf(fileDir, "%s%s/",fileDir, dirname); + } + + return 1; +} + +/*************************************************************************** + * ParseDirectory + * + * List files into one directory + ***************************************************************************/ +int ParseDirectory(void) +{ + int nbfiles = 0; + + /* open directory */ + DIR *dir = opendir(fileDir); + if (dir == NULL) + { + return -1; + } + + struct dirent *entry = readdir(dir); + + /* list entries */ + while ((entry != NULL)&& (nbfiles < MAXFILES)) + { + /* filter entries */ + if ((entry->d_name[0] != '.') + && strncasecmp(".wav", &entry->d_name[strlen(entry->d_name) - 4], 4) + && strncasecmp(".ogg", &entry->d_name[strlen(entry->d_name) - 4], 4) + && strncasecmp(".mp3", &entry->d_name[strlen(entry->d_name) - 4], 4)) + { + memset(&filelist[nbfiles], 0, sizeof (FILEENTRIES)); + sprintf(filelist[nbfiles].filename,"%s",entry->d_name); + if (entry->d_type == DT_DIR) + { + filelist[nbfiles].flags = 1; + } + nbfiles++; + } + + /* next entry */ + entry = readdir(dir); + } + + /* close directory */ + closedir(dir); + + /* Sort the file list */ + qsort(filelist, nbfiles, sizeof(FILEENTRIES), FileSortCallback); + + return nbfiles; +} + +/**************************************************************************** + * LoadFile + * + * This function will load a game file into the ROM buffer. + * This functions return the actual size of data copied into the buffer + * + ****************************************************************************/ +int LoadFile(int selection) +{ + int size, cd_mode1, filetype; + char filename[MAXPATHLEN]; + + /* file path */ + char *filepath = (deviceType == TYPE_RECENT) ? history.entries[selection].filepath : fileDir; + + /* full filename */ + sprintf(filename, "%s%s", filepath, filelist[selection].filename); + + /* DVD hot swap */ + if (!strncmp(filepath, rootdir[TYPE_DVD], strlen(rootdir[TYPE_DVD]))) + { + /* Check if file is still accessible */ + struct stat filestat; + if(stat(filename, &filestat) != 0) + { + /* If not, try to mount DVD */ + if (!MountDVD()) return 0; + } + } + + /* open message box */ + GUI_MsgBoxOpen("Information", "Loading game...", 1); + + /* no cartridge or CD game loaded */ + size = cd_mode1 = 0; + + /* check if virtual CD tray was open */ + if ((system_hw == SYSTEM_MCD) && (cdd.status == CD_OPEN)) + { + /* swap CD image file in (without changing region, system,...) */ + size = cdd_load(filename, (char *)(cdc.ram)); + + /* check if a cartridge is currently loaded */ + if (scd.cartridge.boot) + { + /* CD Mode 1 */ + cd_mode1 = size; + } + else + { + /* update game informations from CD image file header */ + getrominfo((char *)(cdc.ram)); + } + } + + /* no CD image file loaded */ + if (!size) + { + /* close CD tray to force system reset */ + cdd.status = NO_DISC; + + /* load game file */ + size = load_rom(filename); + } + + if (size > 0) + { + /* do not update game basename if a CD was loaded with a cartridge (Mode 1) */ + if (cd_mode1) + { + /* add CD image file to history list */ + filetype = 1; + } + else + { + /* auto-save previous game state */ + slot_autosave(config.s_default,config.s_device); + + /* update game basename (for screenshot, save & cheat files) */ + if (romtype & SYSTEM_SMS) + { + /* Master System ROM file */ + filetype = 2; + sprintf(rom_filename,"ms/%s",filelist[selection].filename); + } + else if (romtype & SYSTEM_GG) + { + /* Game Gear ROM file */ + filetype = 3; + sprintf(rom_filename,"gg/%s",filelist[selection].filename); + } + else if (romtype == SYSTEM_SG) + { + /* SG-1000 ROM file */ + filetype = 4; + sprintf(rom_filename,"sg/%s",filelist[selection].filename); + } + else if (romtype == SYSTEM_MCD) + { + /* CD image file */ + filetype = 1; + sprintf(rom_filename,"cd/%s",filelist[selection].filename); + } + else + { + /* by default, Genesis ROM file */ + filetype = 0; + sprintf(rom_filename,"md/%s",filelist[selection].filename); + } + + /* remove file extension */ + int i = strlen(rom_filename) - 1; + while ((i > 0) && (rom_filename[i] != '.')) i--; + if (i > 0) rom_filename[i] = 0; + } + + /* add/move the file to the top of the history. */ + history_add_file(filepath, filelist[selection].filename, filetype); + + /* recent file list may have changed */ + if (deviceType == TYPE_RECENT) deviceType = -1; + + /* close message box */ + GUI_MsgBoxClose(); + + /* valid image has been loaded */ + return 1; + } + + GUI_WaitPrompt("Error", "Unable to load game"); + return 0; +} + +/**************************************************************************** + * OpenDir + * + * Function to open a directory and load ROM file list. + ****************************************************************************/ +int OpenDirectory(int device, int type) +{ + int max = 0; + + if (device == TYPE_RECENT) + { + /* fetch history list */ + int i; + for(i=0; i < NUM_HISTORY_ENTRIES; i++) + { + if(history.entries[i].filepath[0] > 0) + { + filelist[i].flags = 0; + strncpy(filelist[i].filename,history.entries[i].filename, MAXJOLIET-1); + filelist[i].filename[MAXJOLIET-1] = '\0'; + max++; + } + else + { + /* Found the end of the list. */ + break; + } + } + } + else + { + /* only DVD hot swap is supported */ + if (device == TYPE_DVD) + { + /* try to access root directory */ + DIR *dir = opendir(rootdir[TYPE_DVD]); + if (dir == NULL) + { + /* mount DVD */ + if (!MountDVD()) return 0; + deviceType = -1; + } + else + { + closedir(dir); + } + } + + /* parse last directory */ + fileDir = config.lastdir[type][device]; + max = ParseDirectory(); + if (max <= 0) + { + /* parse root directory */ + strcpy(fileDir, rootdir[device]); + max = ParseDirectory(); + if (max < 0) + { + GUI_WaitPrompt("Error","Unable to open directory !"); + return 0; + } + deviceType = -1; + } + } + + if (max == 0) + { + GUI_WaitPrompt("Error","No files found !"); + return 0; + } + + /* check if device or file type has changed */ + if ((device != deviceType) || (type != fileType)) + { + /* reset current types */ + deviceType = device; + fileType = type; + + /* reset File selector */ + ClearSelector(max); + } + + return 1; +} diff --git a/genplus-gx/gx/fileio/file_load.h b/genplus-gx/gx/fileio/file_load.h new file mode 100644 index 0000000000..fca2aba1c3 --- /dev/null +++ b/genplus-gx/gx/fileio/file_load.h @@ -0,0 +1,72 @@ +/* + * file_load.c + * + * ROM File loading support + * + * Copyright Eke-Eke (2008-2012) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _FILE_FAT_H +#define _FILE_FAT_H + +/* suppported load devices */ +typedef enum +{ + TYPE_SD = 0, +#ifdef HW_RVL + TYPE_USB, +#endif + TYPE_DVD, + TYPE_RECENT +}DEVTYPES; + +/* supported file types */ +typedef enum +{ + FILETYPE_MD = 0, + FILETYPE_CD, + FILETYPE_MS, + FILETYPE_GG, + FILETYPE_SG, + FILETYPE_MAX +}FILETYPES; + +extern int OpenDirectory(int device, int type); +extern int UpdateDirectory(bool go_up, char *filename); +extern int ParseDirectory(void); +extern int LoadFile(int selection); + +extern char rom_filename[256]; + +#endif diff --git a/genplus-gx/gx/fileio/file_slot.c b/genplus-gx/gx/fileio/file_slot.c new file mode 100644 index 0000000000..45d117f70d --- /dev/null +++ b/genplus-gx/gx/fileio/file_slot.c @@ -0,0 +1,830 @@ +/* + * file_slot.c + * + * FAT and Memory Card SRAM/State slots managment + * + * Copyright Eke-Eke (2008-2012), based on original code from Softdev (2006) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "file_slot.h" +#include "file_load.h" +#include "gui.h" +#include "filesel.h" +#include "saveicon.h" + +/** + * libOGC CARD System Work Area + */ +static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32); + +/* Mega CD backup RAM stuff */ +static u32 brm_crc[2]; +static char brm_filename[3][32] = {CD_BRAM_JP, CD_BRAM_EU, CD_BRAM_US}; +static u8 brm_format[0x40] = +{ + 0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x00,0x00,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x53,0x45,0x47,0x41,0x5f,0x43,0x44,0x5f,0x52,0x4f,0x4d,0x00,0x01,0x00,0x00,0x00, + 0x52,0x41,0x4d,0x5f,0x43,0x41,0x52,0x54,0x52,0x49,0x44,0x47,0x45,0x5f,0x5f,0x5f +}; + +/**************************************************************************** + * CardMount + * + * libOGC provides the CARD_Mount function, and it should be all you need. + * However, experience with previous emulators has taught me that you are + * better off doing a little bit more than that! + * + *****************************************************************************/ +static int CardMount(int slot) +{ + int tries = 0; +#ifdef HW_RVL + *(unsigned long *) (0xCD006800) |= 1 << 13; /*** Disable Encryption ***/ +#else + *(unsigned long *) (0xCC006800) |= 1 << 13; /*** Disable Encryption ***/ +#endif + while (tries < 10) + { + VIDEO_WaitVSync (); + if (CARD_Mount(slot, SysArea, NULL) == CARD_ERROR_READY) + return 1; + else + EXI_ProbeReset (); + tries++; + } + return 0; +} + +/**************************************************************************** + * Slot Management + * + * + ****************************************************************************/ +void slot_autoload(int slot, int device) +{ + /* Mega CD backup RAM specific */ + if (!slot && (system_hw == SYSTEM_MCD)) + { + /* automatically load internal backup RAM */ + FILE *fp = fopen(brm_filename[((region_code ^ 0x40) >> 6) - 1], "rb"); + if (fp != NULL) + { + fread(scd.bram, 0x2000, 1, fp); + fclose(fp); + + /* update CRC */ + brm_crc[0] = crc32(0, scd.bram, 0x2000); + } + else + { + /* force internal backup RAM format (does not use previous region backup RAM) */ + scd.bram[0x1fff] = 0; + } + + /* check if internal backup RAM is correctly formatted */ + if (memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20)) + { + /* clear internal backup RAM */ + memset(scd.bram, 0x00, 0x2000 - 0x40); + + /* internal Backup RAM size fields */ + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = 0x00; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (sizeof(scd.bram) / 64) - 3; + + /* format internal backup RAM */ + memcpy(scd.bram + 0x2000 - 0x40, brm_format, 0x40); + + /* clear CRC to force file saving (in case previous region backup RAM was also formatted) */ + brm_crc[0] = 0; + } + + /* automatically load cartridge backup RAM (if enabled) */ + if (scd.cartridge.id) + { + fp = fopen(CART_BRAM, "rb"); + if (fp != NULL) + { + int filesize = scd.cartridge.mask + 1; + int done = 0; + + /* Read into buffer (2k blocks) */ + while (filesize > CHUNKSIZE) + { + fread(scd.cartridge.area + done, CHUNKSIZE, 1, fp); + done += CHUNKSIZE; + filesize -= CHUNKSIZE; + } + + /* Read remaining bytes */ + if (filesize) + { + fread(scd.cartridge.area + done, filesize, 1, fp); + } + + /* close file */ + fclose(fp); + + /* update CRC */ + brm_crc[1] = crc32(0, scd.cartridge.area, scd.cartridge.mask + 1); + } + + /* check if cartridge backup RAM is correctly formatted */ + if (memcmp(scd.cartridge.area + scd.cartridge.mask + 1 - 0x20, brm_format + 0x20, 0x20)) + { + /* clear cartridge backup RAM */ + memset(scd.cartridge.area, 0x00, scd.cartridge.mask + 1); + + /* Cartridge Backup RAM size fields */ + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = (((scd.cartridge.mask + 1) / 64) - 3) >> 8; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (((scd.cartridge.mask + 1) / 64) - 3) & 0xff; + + /* format cartridge backup RAM */ + memcpy(scd.cartridge.area + scd.cartridge.mask + 1 - 0x40, brm_format, 0x40); + } + } + } + + /* configurable SRAM & State auto-saving */ + if ((slot && !(config.s_auto & 2)) || (!slot && !(config.s_auto & 1))) + { + return; + } + + if (strlen(rom_filename)) + { + SILENT = 1; + slot_load(slot, device); + SILENT = 0; + } +} + +void slot_autosave(int slot, int device) +{ + /* Mega CD backup RAM specific */ + if (!slot && (system_hw == SYSTEM_MCD)) + { + /* verify that internal backup RAM has been modified */ + if (crc32(0, scd.bram, 0x2000) != brm_crc[0]) + { + /* check if it is correctly formatted before saving */ + if (!memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20)) + { + FILE *fp = fopen(brm_filename[((region_code ^ 0x40) >> 6) - 1], "wb"); + if (fp != NULL) + { + fwrite(scd.bram, 0x2000, 1, fp); + fclose(fp); + + /* update CRC */ + brm_crc[0] = crc32(0, scd.bram, 0x2000); + } + } + } + + /* verify that cartridge backup RAM has been modified */ + if (scd.cartridge.id && (crc32(0, scd.cartridge.area, scd.cartridge.mask + 1) != brm_crc[1])) + { + /* check if it is correctly formatted before saving */ + if (!memcmp(scd.cartridge.area + scd.cartridge.mask + 1 - 0x20, brm_format + 0x20, 0x20)) + { + FILE *fp = fopen(CART_BRAM, "wb"); + if (fp != NULL) + { + int filesize = scd.cartridge.mask + 1; + int done = 0; + + /* Write to file (2k blocks) */ + while (filesize > CHUNKSIZE) + { + fwrite(scd.cartridge.area + done, CHUNKSIZE, 1, fp); + done += CHUNKSIZE; + filesize -= CHUNKSIZE; + } + + /* Write remaining bytes */ + if (filesize) + { + fwrite(scd.cartridge.area + done, filesize, 1, fp); + } + + /* Close file */ + fclose(fp); + + /* update CRC */ + brm_crc[1] = crc32(0, scd.cartridge.area, scd.cartridge.mask + 1); + } + } + } + } + + /* configurable SRAM & State auto-saving */ + if ((slot && !(config.s_auto & 2)) || (!slot && !(config.s_auto & 1))) + { + return; + } + + if (strlen(rom_filename)) + { + SILENT = 1; + slot_save(slot, device); + SILENT = 0; + } +} + +void slot_autodetect(int slot, int device, t_slot *ptr) +{ + if (!ptr) return; + + char filename[MAXPATHLEN]; + memset(ptr,0,sizeof(t_slot)); + + if (!device) + { + /* FAT support */ + if (slot > 0) + { + sprintf (filename,"%s/saves/%s.gp%d", DEFAULT_PATH, rom_filename, slot - 1); + } + else + { + sprintf (filename,"%s/saves/%s.srm", DEFAULT_PATH, rom_filename); + } + + /* Open file */ + FILE *fp = fopen(filename, "rb"); + if (fp) + { + /* Retrieve date & close */ + struct stat filestat; + stat(filename, &filestat); + struct tm *timeinfo = localtime(&filestat.st_mtime); + ptr->year = 1900 + timeinfo->tm_year; + ptr->month = timeinfo->tm_mon; + ptr->day = timeinfo->tm_mday; + ptr->hour = timeinfo->tm_hour; + ptr->min = timeinfo->tm_min; + fclose(fp); + ptr->valid = 1; + } + } + else + { + /* Memory Card support */ + if (slot > 0) + sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1); + else + sprintf(filename,"MD-%04X.srm", rominfo.realchecksum); + + /* Initialise the CARD system */ + memset(&SysArea, 0, CARD_WORKAREA); + CARD_Init("GENP", "00"); + + /* CARD slot */ + device--; + + /* Mount CARD */ + if (CardMount(device)) + { + /* Open file */ + card_file CardFile; + if (CARD_Open(device, filename, &CardFile) == CARD_ERROR_READY) + { + /* Retrieve date & close */ + card_stat CardStatus; + CARD_GetStatus(device, CardFile.filenum, &CardStatus); + time_t rawtime = CardStatus.time; + struct tm *timeinfo = localtime(&rawtime); + ptr->year = 1900 + timeinfo->tm_year; + ptr->month = timeinfo->tm_mon; + ptr->day = timeinfo->tm_mday; + ptr->hour = timeinfo->tm_hour; + ptr->min = timeinfo->tm_min; + CARD_Close(&CardFile); + ptr->valid = 1; + } + CARD_Unmount(device); + } + } +} + +int slot_delete(int slot, int device) +{ + char filename[MAXPATHLEN]; + int ret = 0; + + if (!device) + { + /* FAT support */ + if (slot > 0) + { + /* remove screenshot */ + sprintf(filename,"%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1); + remove(filename); + + sprintf (filename,"%s/saves/%s.gp%d", DEFAULT_PATH, rom_filename, slot - 1); + } + else + { + sprintf (filename,"%s/saves/%s.srm", DEFAULT_PATH, rom_filename); + } + + /* Delete file */ + ret = remove(filename); + } + else + { + /* Memory Card support */ + if (slot > 0) + sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1); + else + sprintf(filename,"MD-%04X.srm", rominfo.realchecksum); + + /* Initialise the CARD system */ + memset(&SysArea, 0, CARD_WORKAREA); + CARD_Init("GENP", "00"); + + /* CARD slot */ + device--; + + /* Mount CARD */ + if (CardMount(device)) + { + /* Delete file */ + ret = CARD_Delete(device,filename); + CARD_Unmount(device); + } + } + + return ret; +} + +int slot_load(int slot, int device) +{ + char filename[MAXPATHLEN]; + unsigned long filesize, done = 0; + u8 *buffer; + + /* File Type */ + if (slot > 0) + { + GUI_MsgBoxOpen("Information","Loading State ...",1); + } + else + { + if (!sram.on) + { + GUI_WaitPrompt("Error","Backup RAM is disabled !"); + return 0; + } + + GUI_MsgBoxOpen("Information","Loading Backup RAM ...",1); + } + + /* Device Type */ + if (!device) + { + /* FAT file */ + if (slot > 0) + { + sprintf (filename,"%s/saves/%s.gp%d", DEFAULT_PATH, rom_filename, slot - 1); + } + else + { + sprintf (filename,"%s/saves/%s.srm", DEFAULT_PATH, rom_filename); + } + + /* Open file */ + FILE *fp = fopen(filename, "rb"); + if (!fp) + { + GUI_WaitPrompt("Error","Unable to open file !"); + return 0; + } + + /* Get file size */ + fseek(fp, 0, SEEK_END); + filesize = ftell(fp); + fseek(fp, 0, SEEK_SET); + + /* allocate buffer */ + buffer = (u8 *)memalign(32,filesize); + if (!buffer) + { + GUI_WaitPrompt("Error","Unable to allocate memory !"); + fclose(fp); + return 0; + } + + /* Read into buffer (2k blocks) */ + while (filesize > CHUNKSIZE) + { + fread(buffer + done, CHUNKSIZE, 1, fp); + done += CHUNKSIZE; + filesize -= CHUNKSIZE; + } + + /* Read remaining bytes */ + fread(buffer + done, filesize, 1, fp); + done += filesize; + + /* Close file */ + fclose(fp); + } + else + { + /* Memory Card file */ + if (slot > 0) + { + sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1); + } + else + { + sprintf(filename, "MD-%04X.srm", rominfo.realchecksum); + } + + /* Initialise the CARD system */ + char action[64]; + memset(&SysArea, 0, CARD_WORKAREA); + CARD_Init("GENP", "00"); + + /* CARD slot */ + device--; + + /* Attempt to mount the card */ + if (!CardMount(device)) + { + GUI_WaitPrompt("Error","Unable to mount memory card"); + return 0; + } + + /* Retrieve the sector size */ + u32 SectorSize = 0; + int CardError = CARD_GetSectorSize(device, &SectorSize); + if (!SectorSize) + { + sprintf(action, "Invalid sector size (%d)", CardError); + GUI_WaitPrompt("Error",action); + CARD_Unmount(device); + return 0; + } + + /* Open file */ + card_file CardFile; + CardError = CARD_Open(device, filename, &CardFile); + if (CardError) + { + sprintf(action, "Unable to open file (%d)", CardError); + GUI_WaitPrompt("Error",action); + CARD_Unmount(device); + return 0; + } + + /* Get file size */ + filesize = CardFile.len; + if (filesize % SectorSize) + { + filesize = ((filesize / SectorSize) + 1) * SectorSize; + } + + /* Allocate buffer */ + u8 *in = (u8 *)memalign(32, filesize); + if (!in) + { + GUI_WaitPrompt("Error","Unable to allocate memory !"); + CARD_Close(&CardFile); + CARD_Unmount(device); + return 0; + } + + /* Read file sectors */ + while (filesize > 0) + { + CARD_Read(&CardFile, &in[done], SectorSize, done); + done += SectorSize; + filesize -= SectorSize; + } + + /* Close file */ + CARD_Close(&CardFile); + CARD_Unmount(device); + + /* Uncompressed file size */ + memcpy(&filesize, in + 2112, 4); + buffer = (u8 *)memalign(32, filesize); + if (!buffer) + { + free(in); + GUI_WaitPrompt("Error","Unable to allocate memory !"); + return 0; + } + + /* Uncompress file */ + uncompress ((Bytef *)buffer, &filesize, (Bytef *)(in + 2112 + 4), done - 2112 - 4); + free(in); + } + + if (slot > 0) + { + /* Load state */ + if (state_load(buffer) <= 0) + { + free(buffer); + GUI_WaitPrompt("Error","Invalid state file !"); + return 0; + } + } + else + { + /* load SRAM */ + memcpy(sram.sram, buffer, 0x10000); + + /* update CRC */ + sram.crc = crc32(0, sram.sram, 0x10000); + } + + free(buffer); + GUI_MsgBoxClose(); + return 1; +} + +int slot_save(int slot, int device) +{ + char filename[MAXPATHLEN]; + unsigned long filesize, done = 0; + u8 *buffer; + + if (slot > 0) + { + GUI_MsgBoxOpen("Information","Saving State ...",1); + + /* allocate buffer */ + buffer = (u8 *)memalign(32,STATE_SIZE); + if (!buffer) + { + GUI_WaitPrompt("Error","Unable to allocate memory !"); + return 0; + } + + filesize = state_save(buffer); + } + else + { + /* only save if SRAM is enabled */ + if (!sram.on) + { + GUI_WaitPrompt("Error","Backup RAM disabled !"); + return 0; + } + + /* only save if SRAM has been modified */ + if (crc32(0, &sram.sram[0], 0x10000) == sram.crc) + { + GUI_WaitPrompt("Warning","Backup RAM not modified !"); + return 0; + } + + GUI_MsgBoxOpen("Information","Saving Backup RAM ...",1); + + /* allocate buffer */ + buffer = (u8 *)memalign(32, 0x10000); + if (!buffer) + { + GUI_WaitPrompt("Error","Unable to allocate memory !"); + return 0; + } + + /* copy SRAM data */ + memcpy(buffer, sram.sram, 0x10000); + filesize = 0x10000; + + /* update CRC */ + sram.crc = crc32(0, sram.sram, 0x10000); + } + + /* Device Type */ + if (!device) + { + /* FAT filename */ + if (slot > 0) + { + sprintf(filename, "%s/saves/%s.gp%d", DEFAULT_PATH, rom_filename, slot - 1); + } + else + { + sprintf(filename, "%s/saves/%s.srm", DEFAULT_PATH, rom_filename); + } + + /* Open file */ + FILE *fp = fopen(filename, "wb"); + if (!fp) + { + GUI_WaitPrompt("Error","Unable to open file !"); + free(buffer); + return 0; + } + + /* Write from buffer (2k blocks) */ + while (filesize > CHUNKSIZE) + { + fwrite(buffer + done, CHUNKSIZE, 1, fp); + done += CHUNKSIZE; + filesize -= CHUNKSIZE; + } + + /* Write remaining bytes */ + fwrite(buffer + done, filesize, 1, fp); + done += filesize; + + /* Close file */ + fclose(fp); + free(buffer); + + /* Close message box */ + GUI_MsgBoxClose(); + + /* Save state screenshot */ + if (slot > 0) + { + sprintf(filename,"%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1); + gxSaveScreenshot(filename); + } + } + else + { + /* Memory Card filename */ + if (slot > 0) + { + sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1); + } + else + { + sprintf(filename, "MD-%04X.srm", rominfo.realchecksum); + } + + /* Initialise the CARD system */ + char action[64]; + memset(&SysArea, 0, CARD_WORKAREA); + CARD_Init("GENP", "00"); + + /* CARD slot */ + device--; + + /* Attempt to mount the card */ + if (!CardMount(device)) + { + GUI_WaitPrompt("Error","Unable to mount memory card"); + free(buffer); + return 0; + } + + /* Retrieve sector size */ + u32 SectorSize = 0; + int CardError = CARD_GetSectorSize(device, &SectorSize); + if (!SectorSize) + { + sprintf(action, "Invalid sector size (%d)", CardError); + GUI_WaitPrompt("Error",action); + CARD_Unmount(device); + free(buffer); + return 0; + } + + /* Build output buffer */ + u8 *out = (u8 *)memalign(32, filesize + 2112 + 4); + if (!out) + { + GUI_WaitPrompt("Error","Unable to allocate memory !"); + CARD_Unmount(device); + free(buffer); + return 0; + } + + /* Memory Card file header */ + char comment[2][32] = { {"Genesis Plus GX"}, {"SRAM Save"} }; + strcpy (comment[1], filename); + memcpy (&out[0], &icon, 2048); + memcpy (&out[2048], &comment[0], 64); + + /* uncompressed size */ + done = filesize; + memcpy(&out[2112], &done, 4); + + /* compress file */ + compress2 ((Bytef *)&out[2112 + 4], &filesize, (Bytef *)buffer, done, 9); + + /* Adjust file size */ + filesize = filesize + 4 + 2112; + if (filesize % SectorSize) + { + filesize = ((filesize / SectorSize) + 1) * SectorSize; + } + + /* Check if file already exists */ + card_file CardFile; + if (CARD_Open(device, filename, &CardFile) == CARD_ERROR_READY) + { + int size = filesize - CardFile.len; + CARD_Close(&CardFile); + memset(&CardFile,0,sizeof(CardFile)); + + /* Check file new size */ + if (size > 0) + { + CardError = CARD_Create(device, "TEMP", size, &CardFile); + if (CardError) + { + sprintf(action, "Unable to increase file size (%d)", CardError); + GUI_WaitPrompt("Error",action); + CARD_Unmount(device); + free(out); + free(buffer); + return 0; + } + + /* delete temporary file */ + CARD_Close(&CardFile); + memset(&CardFile,0,sizeof(CardFile)); + CARD_Delete(device, "TEMP"); + } + + /* delete previously existing file */ + CARD_Delete(device, filename); + } + + /* Create a new file */ + CardError = CARD_Create(device, filename, filesize, &CardFile); + if (CardError) + { + sprintf(action, "Unable to create file (%d)", CardError); + GUI_WaitPrompt("Error",action); + CARD_Unmount(device); + free(out); + free(buffer); + return 0; + } + + /* Update file informations */ + time_t rawtime; + time(&rawtime); + card_stat CardStatus; + CARD_GetStatus(device, CardFile.filenum, &CardStatus); + CardStatus.icon_addr = 0x0; + CardStatus.icon_fmt = 2; + CardStatus.icon_speed = 1; + CardStatus.comment_addr = 2048; + CardStatus.time = rawtime; + CARD_SetStatus(device, CardFile.filenum, &CardStatus); + + /* Write file sectors */ + while (filesize > 0) + { + CARD_Write(&CardFile, &out[done], SectorSize, done); + filesize -= SectorSize; + done += SectorSize; + } + + /* Close file */ + CARD_Close(&CardFile); + CARD_Unmount(device); + free(out); + free(buffer); + + /* Close message box */ + GUI_MsgBoxClose(); + } + + return 1; +} diff --git a/genplus-gx/gx/fileio/file_slot.h b/genplus-gx/gx/fileio/file_slot.h new file mode 100644 index 0000000000..fe227a8936 --- /dev/null +++ b/genplus-gx/gx/fileio/file_slot.h @@ -0,0 +1,60 @@ +/* + * file_slot.c + * + * FAT and Memory Card SRAM/Savestate files managment + * + * Copyright Eke-Eke (2008-2012), based on original code from Softdev (2006) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _FILE_SLOT_H +#define _FILE_SLOT_H + +typedef struct +{ + int valid; + u16 year; + u8 month; + u8 day; + u8 hour; + u8 min; +} t_slot; + +extern void slot_autoload(int slot, int device); +extern void slot_autosave(int slot, int device); +extern void slot_autodetect(int slot, int device, t_slot *ptr); +extern int slot_delete(int slot, int device); +extern int slot_load(int slot, int device); +extern int slot_save(int slot, int device); + +#endif diff --git a/genplus-gx/gx/fileio/fileio.c b/genplus-gx/gx/fileio/fileio.c new file mode 100644 index 0000000000..4d97eb05a6 --- /dev/null +++ b/genplus-gx/gx/fileio/fileio.c @@ -0,0 +1,258 @@ +/* + * fileio.c + * + * Load a normal file, or ZIP/GZ archive into ROM buffer. + * Returns loaded ROM size (zero if an error occured). + * + * Copyright Eke-Eke (2007-2013), based on original work from Softdev (2006) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "file_load.h" +#include "gui.h" + +/* + * Zip file header definition + */ +typedef struct +{ + unsigned int zipid __attribute__ ((__packed__)); // 0x04034b50 + unsigned short zipversion __attribute__ ((__packed__)); + unsigned short zipflags __attribute__ ((__packed__)); + unsigned short compressionMethod __attribute__ ((__packed__)); + unsigned short lastmodtime __attribute__ ((__packed__)); + unsigned short lastmoddate __attribute__ ((__packed__)); + unsigned int crc32 __attribute__ ((__packed__)); + unsigned int compressedSize __attribute__ ((__packed__)); + unsigned int uncompressedSize __attribute__ ((__packed__)); + unsigned short filenameLength __attribute__ ((__packed__)); + unsigned short extraDataLength __attribute__ ((__packed__)); +} PKZIPHEADER; + + +/* + * Zip files are stored little endian + * Support functions for short and int types + */ +static inline u32 FLIP32 (u32 b) +{ + unsigned int c; + c = (b & 0xff000000) >> 24; + c |= (b & 0xff0000) >> 8; + c |= (b & 0xff00) << 8; + c |= (b & 0xff) << 24; + return c; +} + +static inline u16 FLIP16 (u16 b) +{ + u16 c; + c = (b & 0xff00) >> 8; + c |= (b & 0xff) << 8; + return c; +} + +int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension) +{ + int size = 0; + char in[CHUNKSIZE]; + char msg[64] = "Unable to open file"; + + /* Open file */ + FILE *fd = fopen(filename, "rb"); + + /* Master System & Game Gear BIOS are optional files */ + if (!strcmp(filename,MS_BIOS_US) || !strcmp(filename,MS_BIOS_EU) || !strcmp(filename,MS_BIOS_JP) || !strcmp(filename,GG_BIOS)) + { + /* disable all messages */ + SILENT = 1; + } + + /* Mega CD BIOS are required files */ + if (!strcmp(filename,CD_BIOS_US) || !strcmp(filename,CD_BIOS_EU) || !strcmp(filename,CD_BIOS_JP)) + { + sprintf(msg,"Unable to open %s", filename + 14); + } + + if (!fd) + { + GUI_WaitPrompt("Error", msg); + SILENT = 0; + return 0; + } + + /* Read first chunk */ + fread(in, CHUNKSIZE, 1, fd); + + /* Detect Zip file */ + if (memcmp(in, "PK", 2) == 0) + { + /* Inflate buffer */ + char out[CHUNKSIZE]; + + /* PKZip header pointer */ + PKZIPHEADER *pkzip = (PKZIPHEADER *) in; + + /* Retrieve uncompressed ROM size */ + size = FLIP32(pkzip->uncompressedSize); + + /* Check ROM size */ + if (size > maxsize) + { + fclose(fd); + GUI_WaitPrompt("Error","File is too large"); + SILENT = 0; + return 0; + } + + sprintf (msg, "Unzipping %d bytes ...", size); + GUI_MsgBoxUpdate("Information",msg); + + /* Initialize zip stream */ + z_stream zs; + memset (&zs, 0, sizeof (z_stream)); + zs.zalloc = Z_NULL; + zs.zfree = Z_NULL; + zs.opaque = Z_NULL; + zs.avail_in = 0; + zs.next_in = Z_NULL; + int res = inflateInit2(&zs, -MAX_WBITS); + + if (res != Z_OK) + { + fclose(fd); + GUI_WaitPrompt("Error","Unable to unzip file"); + SILENT = 0; + return 0; + } + + /* Compressed filename offset */ + int offset = sizeof (PKZIPHEADER) + FLIP16(pkzip->filenameLength); + + if (extension) + { + memcpy(extension, &in[offset - 3], 3); + extension[3] = 0; + } + + + /* Initial Zip buffer offset */ + offset += FLIP16(pkzip->extraDataLength); + zs.next_in = (Bytef *)&in[offset]; + + /* Initial Zip remaining chunk size */ + zs.avail_in = CHUNKSIZE - offset; + + /* Start unzipping file */ + do + { + /* Inflate data until output buffer is empty */ + do + { + zs.avail_out = CHUNKSIZE; + zs.next_out = (Bytef *) out; + res = inflate(&zs, Z_NO_FLUSH); + + if (res == Z_MEM_ERROR) + { + inflateEnd(&zs); + fclose(fd); + GUI_WaitPrompt("Error","Unable to unzip file"); + SILENT = 0; + return 0; + } + + offset = CHUNKSIZE - zs.avail_out; + if (offset) + { + memcpy(buffer, out, offset); + buffer += offset; + } + } + while (zs.avail_out == 0); + + /* Read next chunk of zipped data */ + fread(in, CHUNKSIZE, 1, fd); + zs.next_in = (Bytef *)&in[0]; + zs.avail_in = CHUNKSIZE; + } + while (res != Z_STREAM_END); + inflateEnd (&zs); + } + else + { + /* Get file size */ + fseek(fd, 0, SEEK_END); + size = ftell(fd); + fseek(fd, 0, SEEK_SET); + + /* size limit */ + if(size > maxsize) + { + fclose(fd); + GUI_WaitPrompt("Error","File is too large"); + SILENT = 0; + return 0; + } + + sprintf((char *)msg,"Loading %d bytes ...", size); + GUI_MsgBoxUpdate("Information", (char *)msg); + + /* filename extension */ + if (extension) + { + memcpy(extension, &filename[strlen(filename) - 3], 3); + extension[3] = 0; + } + + /* Read into buffer */ + int left = size; + while (left > CHUNKSIZE) + { + fread(buffer, CHUNKSIZE, 1, fd); + buffer += CHUNKSIZE; + left -= CHUNKSIZE; + } + + /* Read remaining bytes */ + fread(buffer, left, 1, fd); + } + + /* Close file */ + fclose(fd); + + /* Return loaded ROM size */ + SILENT = 0; + return size; +} diff --git a/genplus-gx/gx/fileio/fileio.h b/genplus-gx/gx/fileio/fileio.h new file mode 100644 index 0000000000..4e1c6c6050 --- /dev/null +++ b/genplus-gx/gx/fileio/fileio.h @@ -0,0 +1,47 @@ +/* + * fileio.c + * + * Load a normal file, or ZIP/GZ archive into ROM buffer. + * Returns loaded ROM size (zero if an error occured). + * + * Copyright Eke-Eke (2007-2013), based on original work from Softdev (2006) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _FILEIO_H_ +#define _FILEIO_H_ + +/* Function prototypes */ +int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension); + +#endif /* _FILEIO_H_ */ diff --git a/genplus-gx/gx/fileio/history.c b/genplus-gx/gx/fileio/history.c new file mode 100644 index 0000000000..a28219fd3a --- /dev/null +++ b/genplus-gx/gx/fileio/history.c @@ -0,0 +1,138 @@ +/* + * history.c + * + * Generic ROM history list managment + * + * Copyright Eke-Eke (2008-2012), based on original code from Martin Disibio (2008) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "history.h" + +t_history history; + + +/**************************************************************************** + * history_add_file + * + * Adds the given file path to the top of the history list, shifting each + * existing entry in the history down one place. If given file path is + * already in the list then the existing entry is (in effect) moved to the + * top instead. + ****************************************************************************/ +void history_add_file(char *filepath, char *filename, u8 filetype) +{ + /* Create the new entry for this path. */ + t_history_entry newentry; + strncpy(newentry.filepath, filepath, MAXJOLIET - 1); + strncpy(newentry.filename, filename, MAXJOLIET - 1); + newentry.filepath[MAXJOLIET - 1] = '\0'; + newentry.filename[MAXJOLIET - 1] = '\0'; + newentry.filetype = filetype; + + t_history_entry oldentry; /* Old entry is the one being shuffled down a spot. */ + t_history_entry currentry; /* Curr entry is the one that just replaced old path. */ + + /* Initially set curr entry to the new value. */ + memcpy(¤try, &newentry, sizeof(t_history_entry)); + + int i; + for(i=0; i < NUM_HISTORY_ENTRIES; i++) + { + /* Save off the next entry. */ + memcpy(&oldentry, &history.entries[i], sizeof(t_history_entry)); + + /* Overwrite with the previous entry. */ + memcpy(&history.entries[i], ¤try, sizeof(t_history_entry)); + + /* Switch the old entry to the curr entry now. */ + memcpy(¤try, &oldentry, sizeof(t_history_entry)); + + /* If the entry in the list at this spot matches + the new entry then do nothing and let this + entry get deleted. */ + if(strcmp(newentry.filepath, currentry.filepath) == 0 && strcmp(newentry.filename, currentry.filename) == 0) + break; + } + + /* now save to disk */ + history_save(); +} + +void history_save() +{ + /* open file */ + char fname[MAXPATHLEN]; + sprintf (fname, "%s/history.ini", DEFAULT_PATH); + FILE *fp = fopen(fname, "wb"); + if (fp) + { + /* write file */ + fwrite(&history, sizeof(history), 1, fp); + fclose(fp); + } +} + +void history_load(void) +{ + /* open file */ + char fname[MAXPATHLEN]; + sprintf (fname, "%s/history.ini", DEFAULT_PATH); + FILE *fp = fopen(fname, "rb"); + if (fp) + { + /* read file */ + if (fread(&history, sizeof(history), 1, fp) != 1) + { + /* an error ocurred, better clear hoistory */ + memset(&history, 0, sizeof(history)); + } + + /* close file */ + fclose(fp); + } +} + +void history_default(void) +{ + int i; + for(i=0; i < NUM_HISTORY_ENTRIES; i++) + memset(&history.entries[i], 0, sizeof(t_history_entry)); + + /* restore history */ + history_load(); +} + + + diff --git a/genplus-gx/gx/fileio/history.h b/genplus-gx/gx/fileio/history.h new file mode 100644 index 0000000000..e40081a5d8 --- /dev/null +++ b/genplus-gx/gx/fileio/history.h @@ -0,0 +1,69 @@ +/* + * history.c + * + * Generic ROM history list managment + * + * Copyright Eke-Eke (2008-2012), based on original code from Martin Disibio (2008) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _HISTORY_H +#define _HISTORY_H + +#include "filesel.h" + +#define NUM_HISTORY_ENTRIES (10) + +/**************************************************************************** + * ROM Play History + * + ****************************************************************************/ +typedef struct +{ + char filepath[MAXJOLIET]; + char filename[MAXJOLIET]; + u8 filetype; +} t_history_entry; + +typedef struct +{ + t_history_entry entries[NUM_HISTORY_ENTRIES]; +} t_history; + +extern t_history history; +extern void history_add_file(char *filepath, char *filename, u8 filetype); +extern void history_save(void); +extern void history_load(void); +extern void history_default(void); + +#endif diff --git a/genplus-gx/gx/gui/cheats.c b/genplus-gx/gx/gui/cheats.c new file mode 100644 index 0000000000..829044cbfe --- /dev/null +++ b/genplus-gx/gx/gui/cheats.c @@ -0,0 +1,1492 @@ +/* + * cheats.c + * + * Cheats menu + * + * Copyright Eke-Eke (2010-2012) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "file_load.h" +#include "cheats.h" +#include "font.h" +#include "gui.h" + +#define BG_COLOR_1 {0x49,0x49,0x49,0xff} +#define BG_COLOR_2 {0x66,0x66,0x66,0xff} + +#define MAX_CHEATS (150) +#define MAX_DESC_LENGTH (63) + +#ifdef HW_RVL +extern const u8 Key_Minus_wii_png[]; +extern const u8 Key_Plus_wii_png[]; +#else +extern const u8 Key_R_gcn_png[]; +extern const u8 Key_L_gcn_png[]; +#endif +extern const u8 Key_DPAD_png[]; + +typedef struct +{ + char code[12]; + char text[MAX_DESC_LENGTH]; + u8 enable; + u16 data; + u16 old; + u32 address; + u8 *prev; +} CHEATENTRY; + +static int string_offset = 0; +static int selection = 0; +static int offset = 0; +static int type = 0; +static int maxcheats = 0; +static int maxROMcheats = 0; +static int maxRAMcheats = 0; + +static CHEATENTRY cheatlist[MAX_CHEATS]; +static u8 cheatIndexes[MAX_CHEATS]; + +static void cheatmenu_cb(void); + +/*****************************************************************************/ +/* GUI Buttons data */ +/*****************************************************************************/ +static butn_data arrow_up_data = +{ + {NULL,NULL}, + {Button_up_png,Button_up_over_png} +}; + +static butn_data arrow_down_data = +{ + {NULL,NULL}, + {Button_down_png,Button_down_over_png} +}; +static butn_data button_digit_data = +{ + {NULL,NULL}, + {Button_digit_png,Button_digit_over_png} +}; + +/*****************************************************************************/ +/* GUI Arrows button */ +/*****************************************************************************/ + +static gui_butn arrow_up = {&arrow_up_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,0,0,0},14,76,360,32}; +static gui_butn arrow_down = {&arrow_down_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,0,0,0},14,368,360,32}; + + +/*****************************************************************************/ +/* GUI helpers */ +/*****************************************************************************/ +static gui_item action_cancel = +{ + NULL,Key_B_png,"","Exit",10,422,28,28 +}; + +static gui_item action_select = +{ + NULL,Key_A_png,"","Edit Entry",602,422,28,28 +}; + +/*****************************************************************************/ +/* GUI Background images */ +/*****************************************************************************/ +static gui_image bg_cheats[7] = +{ + {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Banner_top_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,0,0,640,108,255}, + {NULL,Banner_bottom_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,0,380,640,100,255}, + {NULL,Main_logo_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,466,40,152,44,255}, + {NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,152}, + {NULL,Frame_s1_png,IMAGE_SLIDE_RIGHT,411,109,372,296,76}, +}; + +/*****************************************************************************/ +/* Menu Items description */ +/*****************************************************************************/ +static gui_item items_cheats[30] = +{ + {NULL,NULL,"","Edit Entry",0,0,0,0}, + {NULL,NULL,"","Edit Entry",0,0,0,0}, + {NULL,NULL,"","Edit Entry",0,0,0,0}, + {NULL,NULL,"","Edit Entry",0,0,0,0}, + {NULL,NULL,"","Edit Entry",0,0,0,0}, + {NULL,NULL,"","Edit Entry",0,0,0,0}, + {NULL,NULL,"","Edit Entry",0,0,0,0}, + {NULL,NULL,"","Edit Entry",0,0,0,0}, + {NULL,NULL,"","Edit Entry",0,0,0,0}, + {NULL,NULL,"","Edit Entry",0,0,0,0}, + {NULL,NULL,"0","Add Character" ,440,136,40,40}, + {NULL,NULL,"1","Add Character" ,486,136,40,40}, + {NULL,NULL,"2","Add Character" ,532,136,40,40}, + {NULL,NULL,"3","Add Character" ,578,136,40,40}, + {NULL,NULL,"4","Add Character" ,440,182,40,40}, + {NULL,NULL,"5","Add Character" ,486,182,40,40}, + {NULL,NULL,"6","Add Character" ,532,182,40,40}, + {NULL,NULL,"7","Add Character" ,578,182,40,40}, + {NULL,NULL,"8","Add Character" ,440,228,40,40}, + {NULL,NULL,"9","Add Character" ,486,228,40,40}, + {NULL,NULL,"A","Add Character" ,532,228,40,40}, + {NULL,NULL,"B","Add Character" ,578,228,40,40}, + {NULL,NULL,"C","Add Character" ,440,274,40,40}, + {NULL,NULL,"D","Add Character" ,486,274,40,40}, + {NULL,NULL,"E","Add Character" ,532,274,40,40}, + {NULL,NULL,"F","Add Character" ,578,274,40,40}, + {NULL,NULL,"del","Backspace" ,440,338,40,40}, + {NULL,NULL,":","Add Separator" ,486,338,40,40}, + {NULL,NULL,"+","Next Characters",532,338,40,40}, + {NULL,NULL,"ok","Save Entry" ,578,338,40,40} +}; + +/*****************************************************************************/ +/* Menu Buttons description */ +/*****************************************************************************/ +static gui_butn buttons_cheats[30] = +{ + {NULL, BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_SELECT_SFX|BUTTON_OVER_SFX,{1,0,0,0},15,108,358,26}, + {NULL, BUTTON_VISIBLE|BUTTON_SELECT_SFX|BUTTON_OVER_SFX,{1,0,0,0},15,134,358,26}, + {NULL, BUTTON_VISIBLE|BUTTON_SELECT_SFX|BUTTON_OVER_SFX,{1,0,0,0},15,160,358,26}, + {NULL, BUTTON_VISIBLE|BUTTON_SELECT_SFX|BUTTON_OVER_SFX,{1,0,0,0},15,186,358,26}, + {NULL, BUTTON_VISIBLE|BUTTON_SELECT_SFX|BUTTON_OVER_SFX,{1,0,0,0},15,212,358,26}, + {NULL, BUTTON_VISIBLE|BUTTON_SELECT_SFX|BUTTON_OVER_SFX,{1,0,0,0},15,238,358,26}, + {NULL, BUTTON_VISIBLE|BUTTON_SELECT_SFX|BUTTON_OVER_SFX,{1,0,0,0},15,264,358,26}, + {NULL, BUTTON_VISIBLE|BUTTON_SELECT_SFX|BUTTON_OVER_SFX,{1,0,0,0},15,290,358,26}, + {NULL, BUTTON_VISIBLE|BUTTON_SELECT_SFX|BUTTON_OVER_SFX,{1,0,0,0},15,316,358,26}, + {NULL, BUTTON_VISIBLE|BUTTON_SELECT_SFX|BUTTON_OVER_SFX,{1,0,0,0},15,342,358,26}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{0,4,0,1},440,136,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{0,4,1,1},486,136,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{0,4,1,1},532,136,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{0,4,1,0},578,136,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,0,1},440,182,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,1,1},486,182,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,1,1},532,182,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,1,0},578,182,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,0,1},440,228,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,1,1},486,228,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,1,1},532,228,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,1,0},578,228,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,0,1},440,274,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,1,1},486,274,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,1,1},532,274,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,4,1,0},578,274,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,0,0,1},440,338,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,0,1,1},486,338,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,0,1,1},532,338,40,40}, + {&button_digit_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{4,0,1,0},578,338,40,40} +}; + +/*****************************************************************************/ +/* Menu description */ +/*****************************************************************************/ +static gui_menu menu_cheats = +{ + "Cheats Manager", + 0,0, + 30,30,7,0, + items_cheats, + buttons_cheats, + bg_cheats, + {&action_cancel, &action_select}, + {&arrow_up,&arrow_down}, + cheatmenu_cb +}; + +static char ggvalidchars[] = "ABCDEFGHJKLMNPRSTVWXYZ0123456789"; + +static char arvalidchars[] = "0123456789ABCDEF"; + +static u32 decode_cheat(char *string, int index) +{ + char *p; + int i,n; + u32 len = 0; + u32 address = 0; + u16 data = 0; + u8 ref = 0; + + /* 16-bit Game Genie code (ABCD-EFGH) */ + if ((strlen(string) >= 9) && (string[4] == '-')) + { + /* 16-bit system only */ + if ((system_hw & SYSTEM_PBC) != SYSTEM_MD) + { + return 0; + } + + for (i = 0; i < 8; i++) + { + if (i == 4) string++; + p = strchr (ggvalidchars, *string++); + if (p == NULL) return 0; + n = p - ggvalidchars; + + switch (i) + { + case 0: + data |= n << 3; + break; + + case 1: + data |= n >> 2; + address |= (n & 3) << 14; + break; + + case 2: + address |= n << 9; + break; + + case 3: + address |= (n & 0xF) << 20 | (n >> 4) << 8; + break; + + case 4: + data |= (n & 1) << 12; + address |= (n >> 1) << 16; + break; + + case 5: + data |= (n & 1) << 15 | (n >> 1) << 8; + break; + + case 6: + data |= (n >> 3) << 13; + address |= (n & 7) << 5; + break; + + case 7: + address |= n; + break; + } + } + + /* code length */ + len = 9; + } + + /* 8-bit Game Genie code (DDA-AAA-XXX) */ + else if ((strlen(string) >= 11) && (string[3] == '-') && (string[7] == '-')) + { + /* 8-bit system only */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + return 0; + } + + /* decode 8-bit data */ + for (i=0; i<2; i++) + { + p = strchr (arvalidchars, *string++); + if (p == NULL) return 0; + n = (p - arvalidchars) & 0xF; + data |= (n << ((1 - i) * 4)); + } + + /* decode 16-bit address (low 12-bits) */ + for (i=0; i<3; i++) + { + if (i==1) string++; /* skip separator */ + p = strchr (arvalidchars, *string++); + if (p == NULL) return 0; + n = (p - arvalidchars) & 0xF; + address |= (n << ((2 - i) * 4)); + } + + /* decode 16-bit address (high 4-bits) */ + p = strchr (arvalidchars, *string++); + if (p == NULL) return 0; + n = (p - arvalidchars) & 0xF; + n ^= 0xF; /* bits inversion */ + address |= (n << 12); + + /* RAM address are also supported */ + if (address >= 0xC000) + { + /* convert to 24-bit Work RAM address */ + address = 0xFF0000 | (address & 0x1FFF); + } + + /* decode reference 8-bit data */ + for (i=0; i<2; i++) + { + string++; /* skip separator and 2nd digit */ + p = strchr (arvalidchars, *string++); + if (p == NULL) return 0; + n = (p - arvalidchars) & 0xF; + ref |= (n << ((1 - i) * 4)); + } + ref = (ref >> 2) | ((ref & 0x03) << 6); /* 2-bit right rotation */ + ref ^= 0xBA; /* XOR */ + + /* update old data value */ + cheatlist[index].old = ref; + + /* code length */ + len = 11; + } + + /* Action Replay code */ + else if (string[6] == ':') + { + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* 16-bit code (AAAAAA:DDDD) */ + if (strlen(string) < 11) return 0; + + /* decode 24-bit address */ + for (i=0; i<6; i++) + { + p = strchr (arvalidchars, *string++); + if (p == NULL) return 0; + n = (p - arvalidchars) & 0xF; + address |= (n << ((5 - i) * 4)); + } + + /* decode 16-bit data */ + string++; + for (i=0; i<4; i++) + { + p = strchr (arvalidchars, *string++); + if (p == NULL) return 0; + n = (p - arvalidchars) & 0xF; + data |= (n << ((3 - i) * 4)); + } + + /* code length */ + len = 11; + } + else + { + /* 8-bit code (xxAAAA:DD) */ + if (strlen(string) < 9) return 0; + + /* decode 16-bit address */ + string+=2; + for (i=0; i<4; i++) + { + p = strchr (arvalidchars, *string++); + if (p == NULL) return 0; + n = (p - arvalidchars) & 0xF; + address |= (n << ((3 - i) * 4)); + } + + /* ROM addresses are not supported */ + if (address < 0xC000) return 0; + + /* convert to 24-bit Work RAM address */ + address = 0xFF0000 | (address & 0x1FFF); + + /* decode 8-bit data */ + string++; + for (i=0; i<2; i++) + { + p = strchr (arvalidchars, *string++); + if (p == NULL) return 0; + n = (p - arvalidchars) & 0xF; + data |= (n << ((1 - i) * 4)); + } + + /* code length */ + len = 9; + } + } + + /* Valid code found ? */ + if (len) + { + /* update cheat address & data values */ + cheatlist[index].address = address; + cheatlist[index].data = data; + } + + /* return code length (0 = invalid) */ + return len; +} + +static void apply_cheats(void) +{ + u8 *ptr; + + /* clear ROM&RAM patches counter */ + maxROMcheats = maxRAMcheats = 0; + + int i; + for (i = 0; i < maxcheats; i++) + { + if (cheatlist[i].enable) + { + if (cheatlist[i].address < cart.romsize) + { + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* patch ROM data */ + cheatlist[i].old = *(u16 *)(cart.rom + (cheatlist[i].address & 0xFFFFFE)); + *(u16 *)(cart.rom + (cheatlist[i].address & 0xFFFFFE)) = cheatlist[i].data; + } + else + { + /* add ROM patch */ + maxROMcheats++; + cheatIndexes[MAX_CHEATS - maxROMcheats] = i; + + /* get current banked ROM address */ + ptr = &z80_readmap[(cheatlist[i].address) >> 10][cheatlist[i].address & 0x03FF]; + + /* check if reference matches original ROM data */ + if (((u8)cheatlist[i].old) == *ptr) + { + /* patch data */ + *ptr = cheatlist[i].data; + + /* save patched ROM address */ + cheatlist[i].prev = ptr; + } + else + { + /* no patched ROM address yet */ + cheatlist[i].prev = NULL; + } + } + } + else if (cheatlist[i].address >= 0xFF0000) + { + /* add RAM patch */ + cheatIndexes[maxRAMcheats++] = i; + } + } + } +} + +static void clear_cheats(void) +{ + int i = maxcheats; + + /* disable cheats in reversed order in case the same address is used by multiple patches */ + while (i > 0) + { + if (cheatlist[i-1].enable) + { + if (cheatlist[i-1].address < cart.romsize) + { + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* restore original ROM data */ + *(u16 *)(cart.rom + (cheatlist[i-1].address & 0xFFFFFE)) = cheatlist[i-1].old; + } + else + { + /* check if previous banked ROM address has been patched */ + if (cheatlist[i-1].prev != NULL) + { + /* restore original data */ + *cheatlist[i-1].prev = cheatlist[i-1].old; + + /* no more patched ROM address */ + cheatlist[i-1].prev = NULL; + } + } + } + } + + i--; + } +} + +static void switch_chars(void) +{ + int i; + gui_menu *m = &menu_cheats; + + if (m->items[10].text[0] == '0') + { + m->items[10].text[0] = 'G'; + m->items[11].text[0] = 'H'; + m->items[12].text[0] = 'J'; + m->items[13].text[0] = 'K'; + m->items[14].text[0] = 'L'; + m->items[15].text[0] = 'M'; + m->items[16].text[0] = 'N'; + m->items[17].text[0] = 'P'; + m->items[18].text[0] = 'R'; + m->items[19].text[0] = 'S'; + m->items[20].text[0] = 'T'; + m->items[21].text[0] = 'V'; + m->items[22].text[0] = 'W'; + m->items[23].text[0] = 'X'; + m->items[24].text[0] = 'Y'; + m->items[25].text[0] = 'Z'; + } + else if (m->items[10].text[0] == 'G') + { + m->items[10].text[0] = '0'; + m->items[11].text[0] = '1'; + m->items[12].text[0] = '2'; + m->items[13].text[0] = '3'; + m->items[14].text[0] = '4'; + m->items[15].text[0] = '5'; + m->items[16].text[0] = '6'; + m->items[17].text[0] = '7'; + m->items[18].text[0] = '8'; + m->items[19].text[0] = '9'; + m->items[20].text[0] = 'A'; + m->items[21].text[0] = 'B'; + m->items[22].text[0] = 'C'; + m->items[23].text[0] = 'D'; + m->items[24].text[0] = 'E'; + m->items[25].text[0] = 'F'; + } + else if (m->items[10].text[0] == 'A') + { + m->items[10].text[0] = 'Q'; + m->items[11].text[0] = 'R'; + m->items[12].text[0] = 'S'; + m->items[13].text[0] = 'T'; + m->items[14].text[0] = 'U'; + m->items[15].text[0] = 'V'; + m->items[16].text[0] = 'W'; + m->items[17].text[0] = 'X'; + m->items[18].text[0] = 'Y'; + m->items[19].text[0] = 'Z'; + m->items[20].text[0] = '0'; + m->items[21].text[0] = '1'; + m->items[22].text[0] = '2'; + m->items[23].text[0] = '3'; + m->items[24].text[0] = '4'; + m->items[25].text[0] = '5'; + } + else if (m->items[10].text[0] == 'Q') + { + m->items[10].text[0] = '6'; + m->items[11].text[0] = '7'; + m->items[12].text[0] = '8'; + m->items[13].text[0] = '9'; + + /* hide unused buttons */ + for (i=14; i<26; i++) + { + m->buttons[i].state &= ~BUTTON_VISIBLE; + } + m->buttons[10].shift[1] = 16; + m->buttons[11].shift[1] = 16; + m->buttons[12].shift[1] = 16; + m->buttons[13].shift[1] = 16; + m->buttons[26].shift[0] = 16; + m->buttons[27].shift[0] = 16; + m->buttons[28].shift[0] = 16; + m->buttons[29].shift[0] = 16; + } + else if (m->items[10].text[0] == '6') + { + m->items[10].text[0] = 'A'; + m->items[11].text[0] = 'B'; + m->items[12].text[0] = 'C'; + m->items[13].text[0] = 'D'; + m->items[14].text[0] = 'E'; + m->items[15].text[0] = 'F'; + m->items[16].text[0] = 'G'; + m->items[17].text[0] = 'H'; + m->items[18].text[0] = 'I'; + m->items[19].text[0] = 'J'; + m->items[20].text[0] = 'K'; + m->items[21].text[0] = 'L'; + m->items[22].text[0] = 'M'; + m->items[23].text[0] = 'N'; + m->items[24].text[0] = 'O'; + m->items[25].text[0] = 'P'; + + /* show previously unused buttons */ + for (i=14; i<26; i++) + { + m->buttons[i].state |= BUTTON_VISIBLE; + } + m->buttons[10].shift[1] = 4; + m->buttons[11].shift[1] = 4; + m->buttons[12].shift[1] = 4; + m->buttons[13].shift[1] = 4; + m->buttons[26].shift[0] = 4; + m->buttons[27].shift[0] = 4; + m->buttons[28].shift[0] = 4; + m->buttons[29].shift[0] = 4; + } +} + +static void cheatmenu_cb(void) +{ + int i; + int yoffset = 108; + gui_image bar_over; + gui_image star; + char temp[MAX_DESC_LENGTH]; + + /* Initialize textures */ + bar_over.texture = gxTextureOpenPNG(Overlay_bar_png,0); + star.texture = gxTextureOpenPNG(Star_full_png,0); + + /* Draw browser array */ + gxDrawRectangle(15, 108, 358, 26, 127, (GXColor)BG_COLOR_1); + gxDrawRectangle(15, 134, 358, 26, 127, (GXColor)BG_COLOR_2); + gxDrawRectangle(15, 160, 358, 26, 127, (GXColor)BG_COLOR_1); + gxDrawRectangle(15, 186, 358, 26, 127, (GXColor)BG_COLOR_2); + gxDrawRectangle(15, 212, 358, 26, 127, (GXColor)BG_COLOR_1); + gxDrawRectangle(15, 238, 358, 26, 127, (GXColor)BG_COLOR_2); + gxDrawRectangle(15, 264, 358, 26, 127, (GXColor)BG_COLOR_1); + gxDrawRectangle(15, 290, 358, 26, 127, (GXColor)BG_COLOR_2); + gxDrawRectangle(15, 316, 358, 26, 127, (GXColor)BG_COLOR_1); + gxDrawRectangle(15, 342, 358, 26, 127, (GXColor)BG_COLOR_2); + + /* Draw Cheat list */ + for (i=0; ((offset + i) < maxcheats) && (i < 10); i++) + { + if (i == selection) + { + /* selection bar */ + gxDrawTexture(bar_over.texture,16,yoffset+1,356,24,255); + + /* cheat description need to be specifically handled */ + if (type) + { + /* check if text is being edited */ + if (menu_cheats.bg_images[6].state & IMAGE_VISIBLE) + { + /* adjust offset so that last characters are visible */ + string_offset += FONT_writeCenter(cheatlist[offset + i].text+string_offset,16,40,366,yoffset+21,(GXColor)WHITE); + } + else + { + /* scroll text (speed = 1/10 frame) */ + if ((string_offset/10) >= strlen(cheatlist[offset + i].text)) + { + string_offset = 0; + } + + if (string_offset) + { + sprintf(temp,"%s ",cheatlist[offset + i].text+string_offset/10); + strncat(temp, cheatlist[offset + i].text, string_offset/10); + } + else + { + strcpy(temp, cheatlist[offset + i].text); + } + + if (FONT_writeCenter(temp,16,40,366,yoffset+21,(GXColor)WHITE)) + { + /* scroll text if string does not fit */ + string_offset ++; + } + } + } + else + { + FONT_writeCenter(cheatlist[offset + i].code,18,40,366,yoffset+22,(GXColor)WHITE); + } + } + else + { + if (type) + { + FONT_writeCenter(cheatlist[offset + i].text,16,40,366,yoffset+21,(GXColor)WHITE); + } + else + { + FONT_writeCenter(cheatlist[offset + i].code,18,40,366,yoffset+22,(GXColor)WHITE); + } + } + + /* draw cheat enable mark */ + if (cheatlist[offset + i].enable) + { + gxDrawTexture(star.texture,20,yoffset+5,16,16,255); + } + + yoffset += 26; + } + + /* New Entry */ + if (i < 10) + { + if (i == selection) + { + /* selection bar */ + gxDrawTexture(bar_over.texture,16,yoffset+1,356,24,255); + + /* check if new code is being edited */ + if (menu_cheats.bg_images[6].state & IMAGE_VISIBLE) + { + FONT_writeCenter(cheatlist[offset + selection].code,18,40,366,yoffset+22,(GXColor)WHITE); + } + else + { + FONT_writeCenter("New Code",18,40,366,yoffset+22,(GXColor)WHITE); + } + } + else + { + FONT_writeCenter("New Code",18,40,366,yoffset+22,(GXColor)WHITE); + } + } + + gxTextureClose(&bar_over.texture); + gxTextureClose(&star.texture); + + /* Extra helpers */ + if (maxcheats && !(menu_cheats.bg_images[6].state & IMAGE_VISIBLE)) + { + /* switch between cheat code & description preview */ + gui_image key_switch; + key_switch.texture = gxTextureOpenPNG(Key_DPAD_png,0); +#ifdef HW_RVL + gxDrawTexture(key_switch.texture,268,424,24,24,255); + FONT_write(type ? "View\nCode":"View\nText",16,300,436,640,(GXColor)WHITE); +#else + gxDrawTexture(key_switch.texture,272,424,24,24,255); + FONT_write(type ? "View\nCode":"View\nText",16,304,436,640,(GXColor)WHITE); +#endif + gxTextureClose(&key_switch.texture); + + /* delete & enable cheats */ + if ((offset + selection) < maxcheats) + { + gui_image key_enable; + gui_image key_delete; + #ifdef HW_RVL + key_enable.texture = gxTextureOpenPNG(Key_Plus_wii_png,0); + key_delete.texture = gxTextureOpenPNG(Key_Minus_wii_png,0); + gxDrawTexture(key_enable.texture,152,424,24,24,255); + gxDrawTexture(key_delete.texture,372,424,24,24,255); + FONT_write(cheatlist[offset + selection].enable ? "Disable\nCheat":"Enable\nCheat",16,184,436,640,(GXColor)WHITE); + FONT_write("Delete\nCheat",16,404,436,640,(GXColor)WHITE); + #else + key_enable.texture = gxTextureOpenPNG(Key_L_gcn_png,0); + key_delete.texture = gxTextureOpenPNG(Key_R_gcn_png,0); + gxDrawTexture(key_enable.texture,136,426,44,20,255); + gxDrawTexture(key_delete.texture,368,426,44,20,255); + FONT_write(cheatlist[offset + selection].enable ? "Disable\nCheat":"Enable\nCheat",16,188,436,640,(GXColor)WHITE); + FONT_write("Delete\nCheat",16,420,436,640,(GXColor)WHITE); + #endif + gxTextureClose(&key_enable.texture); + gxTextureClose(&key_delete.texture); + } + } +} + + +/**************************************************************************** + * CheatMenu + * + * Manage cheats for the currently loaded game + * + ****************************************************************************/ +void CheatMenu(void) +{ + int i, update = 0; + int digit_cnt = 0; + int max = 0; + char temp[256]; + char *str = NULL; + gui_menu *m = &menu_cheats; + + /* clear existing ROM patches */ + clear_cheats(); + + /* reset scrolling */ + string_offset = 0; + + /* background overlay */ + if (config.bg_overlay) + { + bg_cheats[1].state |= IMAGE_VISIBLE; + } + else + { + bg_cheats[1].state &= ~IMAGE_VISIBLE; + } + + /* selected item */ + m->selected = selection; + + /* slide-in menu */ + GUI_InitMenu(m); + GUI_DrawMenuFX(m,30,0); + m->cb = cheatmenu_cb; + + /* lock background elements */ + m->bg_images[2].state &= ~IMAGE_SLIDE_TOP; + m->bg_images[3].state &= ~IMAGE_SLIDE_BOTTOM; + m->bg_images[4].state &= ~IMAGE_SLIDE_TOP; + + while (update != -1) + { + /* update arrows buttons */ + if (offset > 0) m->arrows[0]->state |= BUTTON_VISIBLE; + else m->arrows[0]->state &= ~BUTTON_VISIBLE; + if ((offset + 10) < (maxcheats + 1)) m->arrows[1]->state |= BUTTON_VISIBLE; + else m->arrows[1]->state &= ~BUTTON_VISIBLE; + + /* draw menu */ + GUI_DrawMenu(m); + + /* restore cheats offset */ + if (!(menu_cheats.bg_images[6].state & IMAGE_VISIBLE)) + { + m->offset = offset; + m->max_items = maxcheats + 1; + m->max_buttons = 10; + } + + /* update menu */ + update = GUI_UpdateMenu(m); + + /* update selected cheat */ + if ((m->selected < 10) && (selection != m->selected)) + { + selection = m->selected; + string_offset = 0; + } + + /* save offset then restore default */ + if (!(m->bg_images[6].state & IMAGE_VISIBLE)) + { + offset = m->offset; + m->offset = 0; + m->max_items = m->max_buttons = 30; + } + + + /* handle pressed buttons */ + if (update > 0) + { + switch (m->selected) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: /* Edit cheat */ + { + if (type && ((selection + offset) != maxcheats)) + { + /* cheat description */ + str = cheatlist[offset + selection].text; + strcpy(temp, str); + max = MAX_DESC_LENGTH - 2; + digit_cnt = strlen(str); + if (digit_cnt <= max) + { + str[digit_cnt] = '*'; + str[digit_cnt+1] = 0; + } + + /* init specific characters */ + m->items[10].text[0] = '6'; + m->items[27].text[0] = ' '; + strcpy(m->items[27].comment,"Add White Space"); + switch_chars(); + } + else + { + /* cheat code */ + str = cheatlist[offset + selection].code; + strcpy(temp, str); + if ((offset + selection) == maxcheats) + { + /* initialize code */ + max = 0; + digit_cnt = 0; + str[0] = '*'; + str[1] = 0; + } + else + { + /* code type */ + if (str[6] == ':') + { + /* Action Replay code */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* 16-bit code */ + max = 10; + } + else + { + /* 8-bit code */ + max = 8; + } + } + else if (str[4] == '-') + { + /* 16-bit Game Genie code */ + max = 8; + } + else + { + /* 8-bit Game Genie code */ + max = 10; + } + + /* set cursor to end of code */ + digit_cnt = max + 1; + } + + /* init specific characters */ + m->items[10].text[0] = 'G'; + m->items[27].text[0] = ':'; + strcpy(m->items[27].comment,"Add Code Separator"); + switch_chars(); + } + + /* show digit buttons */ + for (i=10; i<30; i++) m->buttons[i].state |= BUTTON_VISIBLE; + + /* show right window */ + m->bg_images[6].state |= IMAGE_VISIBLE; + + /* disable left buttons */ + for (i=0; i<10; i++) m->buttons[i].state &= ~BUTTON_ACTIVE; + + /* disable arrow buttons */ + m->arrows[0]->state &= ~BUTTON_ACTIVE; + m->arrows[1]->state &= ~BUTTON_ACTIVE; + + /* slide in right window */ + GUI_DrawMenuFX(m,20,0); + + /* update helper */ + strcpy(action_cancel.comment,"Cancel"); + + /* select first digit */ + m->selected = 10; + + /* reset scrolling */ + string_offset = 0; + break; + } + + case 26: /* Backspace */ + { + if (digit_cnt > 0) + { + /* delete last character */ + str[digit_cnt--] = 0; + + /* code separator is being deleted */ + if ((str[digit_cnt] == ':') || (str[digit_cnt] == '-')) + { + /* reset detected code type (except 8-bit Game Genie code using 2 separators) */ + if (((system_hw & SYSTEM_PBC) == SYSTEM_MD) || (digit_cnt != 7)) + { + max = 0; + } + } + + /* edit mark */ + str[digit_cnt] = '*'; + + /* update scroll value if necessary */ + if (string_offset > 0) string_offset--; + } + break; + } + + case 27: + { + if (type && ((offset + selection) != maxcheats)) + { + /* SPACE character */ + if (digit_cnt <= max) + { + str[digit_cnt++] = ' '; + str[digit_cnt] = 0; + if (digit_cnt <= max) + { + str[digit_cnt] = '*'; + str[digit_cnt+1] = 0; + } + } + } + else + { + /* Separator character */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* 16-bit codes */ + if (digit_cnt == 4) + { + /* Game Genie code */ + max = 8; + str[4] = '-'; + } + else if ((digit_cnt == 6) && (max != 8)) + { + /* Action Replay code */ + max = 10; + str[6] = ':'; + } + else + { + break; + } + } + else + { + /* 8-bit codes */ + if (digit_cnt == 3) + { + /* Game Genie code */ + max = 10; + str[3] = '-'; + } + else if ((digit_cnt == 7) && (max == 10)) + { + /* Game Genie code (last part) */ + str[7] = '-'; + } + else if ((digit_cnt == 6) && (max != 10)) + { + /* Action Replay code */ + max = 8; + str[6] = ':'; + } + else + { + break; + } + } + + digit_cnt++; + str[digit_cnt] = '*'; + str[digit_cnt+1] = 0; + } + break; + } + + case 28: /* Next character set */ + { + GUI_DrawMenuFX(m,40,1); + switch_chars(); + GUI_DrawMenuFX(m,40,0); + break; + } + + case 29: /* Validate entry */ + { + /* check if entry is valid */ + if (type && ((offset + selection) != maxcheats)) + { + str[digit_cnt] = 0; + update = -1; + } + else if (max && (digit_cnt > max)) + { + if (decode_cheat(cheatlist[offset + selection].code, offset + selection)) + { + /* new cheat ? */ + if ((offset + selection) == maxcheats) + { + /* increase cheat count */ + maxcheats++; + + /* enable cheat by default */ + cheatlist[offset + selection].enable = 1; + + /* no description by default */ + strcpy(cheatlist[offset + selection].text,"No Description"); + } + + /* return to cheat selection */ + update = -1; + } + else + { + GUI_WaitPrompt("Error", "Invalid Cheat Code"); + } + } + break; + } + + default: /* Add Character */ + { + /* force code separator if none has been set yet */ + if ((max == 0) && (digit_cnt == 6)) break; + + /* force 8-bit Game Genie code last separator */ + if (((system_hw & SYSTEM_PBC) != SYSTEM_MD) && (max == 10) && (digit_cnt == 7)) break; + + /* add character */ + if ((digit_cnt <= max) || (max == 0)) + { + str[digit_cnt++] = m->items[m->selected].text[0]; + str[digit_cnt] = 0; + if ((digit_cnt <= max) || (max == 0)) + { + str[digit_cnt] = '*'; + str[digit_cnt+1] = 0; + } + if (string_offset > 0) string_offset ++; + } + break; + } + } + } + else if (update < 0) + { + if (m->bg_images[6].state & IMAGE_VISIBLE) + { + /* Restore old entry */ + strcpy(str, temp); + } + } + else + { + if (maxcheats && !(m->bg_images[6].state & IMAGE_VISIBLE)) + { + if ((m_input.keys & PAD_BUTTON_LEFT) || (m_input.keys & PAD_BUTTON_RIGHT)) + { + /* Switch between cheat code & description */ + type ^= 1; + + /* reset scrolling */ + string_offset = 0; + } + + if ((offset + selection) < maxcheats) + { + /* Special inputs */ + if (m_input.keys & PAD_TRIGGER_R) + { + /* sort cheat list */ + for (i = offset + selection + 1; i < maxcheats; i++) + { + strcpy(cheatlist[i-1].text,cheatlist[i].text); + strcpy(cheatlist[i-1].code,cheatlist[i].code); + cheatlist[i-1].address = cheatlist[i].address; + cheatlist[i-1].data = cheatlist[i].data; + cheatlist[i-1].enable = cheatlist[i].enable; + } + + /* clear last cheat */ + cheatlist[maxcheats-1].text[0] = 0; + cheatlist[maxcheats-1].code[0] = 0; + cheatlist[maxcheats-1].address = 0; + cheatlist[maxcheats-1].data = 0; + cheatlist[maxcheats-1].enable = 0; + + /* disable last button */ + if ((maxcheats - offset) < 10) + { + m->buttons[maxcheats - offset].state &= ~BUTTON_ACTIVE; + m->buttons[maxcheats - offset - 1].shift[1] = 0; + } + + /* decrease cheat count */ + maxcheats--; + + /* reset scrolling */ + string_offset = 0; + } + else if (m_input.keys & PAD_TRIGGER_L) + { + /* cheat ON/OFF */ + cheatlist[offset + selection].enable ^= 1; + } + } + } + } + + if (update < 0) + { + if (m->bg_images[6].state & IMAGE_VISIBLE) + { + /* slide out right window */ + GUI_DrawMenuFX(m,20,1); + + /* hide digit buttons */ + for (i=10; i<30; i++) m->buttons[i].state &= ~BUTTON_VISIBLE; + + /* hide right window */ + m->bg_images[6].state &= ~IMAGE_VISIBLE; + + /* update left buttons */ + for (i=0; i<10; i++) + { + if ((offset + i) < maxcheats) + { + m->buttons[i].state |= BUTTON_ACTIVE; + m->buttons[i].shift[1] = 1; + } + else if ((offset + i) == maxcheats) + { + m->buttons[i].state |= BUTTON_ACTIVE; + m->buttons[i].shift[1] = 0; + } + else + { + m->buttons[i].state &= ~BUTTON_ACTIVE; + m->buttons[i].shift[1] = 0; + } + } + + /* enable arrow buttons */ + m->arrows[0]->state |= BUTTON_ACTIVE; + m->arrows[1]->state |= BUTTON_ACTIVE; + + /* restore helper */ + strcpy(action_cancel.comment,"Back"); + + /* select current cheat */ + m->selected = selection; + + /* stay in menu */ + update = 0; + } + } + } + + /* apply ROM patches */ + apply_cheats(); + + /* save cheats to file */ + sprintf(temp, "%s/cheats/%s.pat", DEFAULT_PATH, rom_filename); + + if (maxcheats) + { + /* open file */ + FILE *f = fopen(temp, "w"); + + /* write cheats */ + if (f) + { + for (i=0; ibg_images[2].state |= IMAGE_SLIDE_TOP; + m->bg_images[3].state |= IMAGE_SLIDE_BOTTOM; + m->bg_images[4].state |= IMAGE_SLIDE_TOP; + + /* leave menu */ + m->cb = NULL; + GUI_DeleteMenu(m); + GUI_DrawMenuFX(m,30,1); +} + + +/**************************************************************************** + * CheatLoad + * + * Load cheats from associated .pat file, called when loading a new game + * ROM patches are automatically applied. + * RAM patches are applied once per frame. + * + ****************************************************************************/ +void CheatLoad(void) +{ + int len; + int cnt = 0; + char temp[256]; + + /* reset cheat count */ + maxcheats = 0; + + /* make cheat filename */ + sprintf(temp, "%s/cheats/%s.pat", DEFAULT_PATH, rom_filename); + + /* open file */ + FILE *f = fopen(temp, "r"); + if (f) + { + /* clear string */ + memset(temp, 0, 256); + + /* read cheats from file (one line per cheat) */ + while (fgets(temp, 256, f) && (maxcheats < MAX_CHEATS) && (cnt < MAX_CHEATS)) + { + /* remove CR & EOL chars */ + if ((temp[strlen(temp) - 2] == 0x0d) || (temp[strlen(temp) - 2] == 0x0a)) temp[strlen(temp) - 2] = 0; + else temp[strlen(temp) - 1] = 0; + + /* check cheat validty */ + len = decode_cheat(temp, maxcheats); + + if (len) + { + /* copy cheat code */ + strncpy(cheatlist[maxcheats].code, temp, len); + cheatlist[maxcheats].code[len] = 0; + len++; + + /* jump TAB and SPACE characters */ + while ((temp[len] == 0x20) || (temp[len] == 0x09)) len++; + + /* copy cheat description */ + strncpy(cheatlist[maxcheats].text, &temp[len], MAX_DESC_LENGTH - 1); + cheatlist[maxcheats].text[MAX_DESC_LENGTH - 1] = 0; + + /* increment cheat count */ + maxcheats++; + } + else if (!strcmp(temp,"ON") && config.autocheat) + { + /* enable flag */ + cheatlist[cnt++].enable = 1; + } + else if (!strcmp(temp,"OFF") && config.autocheat) + { + /* disable flag */ + cheatlist[cnt++].enable = 0; + } + } + + /* by default, disable cheats that were not flagged */ + while (cnt < maxcheats) cheatlist[cnt++].enable = 0; + + /* close file */ + fclose(f); + } + + /* apply ROM patches */ + apply_cheats(); + + /* adjust menu buttons */ + for (cnt=0; cnt<10; cnt++) + { + if (cnt < maxcheats) + { + menu_cheats.buttons[cnt].state |= BUTTON_ACTIVE; + menu_cheats.buttons[cnt].shift[1] = 1; + } + else if (cnt == maxcheats) + { + menu_cheats.buttons[cnt].state |= BUTTON_ACTIVE; + menu_cheats.buttons[cnt].shift[1] = 0; + } + else + { + menu_cheats.buttons[cnt].shift[1] = 0; + menu_cheats.buttons[cnt].state &= ~BUTTON_ACTIVE; + } + } + + /* reset menu */ + selection = offset = 0; +} + +/**************************************************************************** + * RAMCheatUpdate + * + * Apply RAM patches (this should be called once per frame) + * + ****************************************************************************/ +void RAMCheatUpdate(void) +{ + int index, cnt = maxRAMcheats; + + while (cnt) + { + /* get cheat index */ + index = cheatIndexes[--cnt]; + + /* apply RAM patch */ + if (cheatlist[index].data & 0xFF00) + { + /* word patch */ + *(u16 *)(work_ram + (cheatlist[index].address & 0xFFFE)) = cheatlist[index].data; + } + else + { + /* byte patch */ + work_ram[cheatlist[index].address & 0xFFFF] = cheatlist[index].data; + } + } +} + + +/**************************************************************************** + * ROMCheatUpdate + * + * Apply ROM patches (this should be called each time banking is changed) + * + ****************************************************************************/ +void ROMCheatUpdate(void) +{ + int index, cnt = maxROMcheats; + u8 *ptr; + + while (cnt) + { + /* get cheat index */ + index = cheatIndexes[MAX_CHEATS - cnt]; + + /* check if previous banked ROM address was patched */ + if (cheatlist[index].prev != NULL) + { + /* restore original data */ + *cheatlist[index].prev = cheatlist[index].old; + + /* no more patched ROM address */ + cheatlist[index].prev = NULL; + } + + /* get current banked ROM address */ + ptr = &z80_readmap[(cheatlist[index].address) >> 10][cheatlist[index].address & 0x03FF]; + + /* check if reference matches original ROM data */ + if (((u8)cheatlist[index].old) == *ptr) + { + /* patch data */ + *ptr = cheatlist[index].data; + + /* save patched ROM address */ + cheatlist[index].prev = ptr; + } + + /* next ROM patch */ + cnt--; + } +} diff --git a/genplus-gx/gx/gui/cheats.h b/genplus-gx/gx/gui/cheats.h new file mode 100644 index 0000000000..e6759a6a8a --- /dev/null +++ b/genplus-gx/gx/gui/cheats.h @@ -0,0 +1,50 @@ +/* + * cheats.c + * + * Cheats menu + * + * Copyright Eke-Eke (2010-2012) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _CHEATS_H +#define _CHEATS_H + +#define CHEATS_UPDATE() ROMCheatUpdate() + +extern void CheatMenu(void); +extern void CheatLoad(void); +extern void RAMCheatUpdate(void); +extern void ROMCheatUpdate(void); + +#endif diff --git a/genplus-gx/gx/gui/filesel.c b/genplus-gx/gx/gui/filesel.c new file mode 100644 index 0000000000..0ed07a0c4c --- /dev/null +++ b/genplus-gx/gx/gui/filesel.c @@ -0,0 +1,645 @@ +/* + * filesel.c + * + * ROM File Browser + * + * Copyright Eke-Eke (2009-2013) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "filesel.h" +#include "font.h" +#include "gui.h" +#include "file_load.h" +#include "history.h" + +#define BG_COLOR_1 {0x49,0x49,0x49,0xff} +#define BG_COLOR_2 {0x66,0x66,0x66,0xff} + +#define SCROLL_SPEED 10 + +extern const u8 Browser_dir_png[]; +extern const u8 Snap_empty_png[]; +extern const u8 Cart_md_png[]; +extern const u8 Cart_ms_png[]; +extern const u8 Cart_gg_png[]; +extern const u8 Cart_sg_png[]; + +FILEENTRIES filelist[MAXFILES]; + +static int offset = 0; +static int selection = 0; +static int maxfiles = 0; +static int string_offset = 0; +static char prev_folder[MAXJOLIET]; +static void selector_cb(void); + +/*****************************************************************************/ +/* GUI Buttons data */ +/*****************************************************************************/ +static butn_data arrow_up_data = +{ + {NULL,NULL}, + {Button_up_png,Button_up_over_png} +}; + +static butn_data arrow_down_data = +{ + {NULL,NULL}, + {Button_down_png,Button_down_over_png} +}; + +/*****************************************************************************/ +/* GUI Arrows button */ +/*****************************************************************************/ + +static gui_butn arrow_up = {&arrow_up_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,0,0,0},14,76,360,32}; +static gui_butn arrow_down = {&arrow_down_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,0,0,0},14,368,360,32}; + +/*****************************************************************************/ +/* GUI helpers */ +/*****************************************************************************/ +static gui_item action_cancel = +{ + NULL,Key_B_png,"","Previous Directory",10,422,28,28 +}; + +static gui_item action_select = +{ + NULL,Key_A_png,"","Load ROM file",602,422,28,28 +}; + +/*****************************************************************************/ +/* GUI Background images */ +/*****************************************************************************/ +static gui_image bg_filesel[14] = +{ + {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255}, + {NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255}, + {NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255}, + {NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,152}, + {NULL,Frame_s2_png,0,384,264,248,140,152}, + {NULL,Snap_empty_png,IMAGE_VISIBLE,424,148,160,112,255}, + {NULL,NULL,0,424,148,160,112,255}, + {NULL,NULL,0,388,147,240,152,255}, + {NULL,NULL,0,388,147,240,152,255}, + {NULL,NULL,0,392,118,232,148,255}, + {NULL,NULL,0,414,116,184,188,255}, + {NULL,NULL,0,416,144,180,228,255} +}; + +static const u8 *Cart_png[FILETYPE_MAX] = +{ + Cart_md_png, + Cart_md_png, + Cart_ms_png, + Cart_gg_png, + Cart_sg_png +}; + +static const char *Cart_dir[FILETYPE_MAX] = +{ + "md", + "cd", + "ms", + "gg", + "sg" +}; + +/*****************************************************************************/ +/* GUI Descriptor */ +/*****************************************************************************/ +static gui_menu menu_selector = +{ + "Game Selection", + -1,-1, + 0,0,14,0, + NULL, + NULL, + bg_filesel, + {&action_cancel, &action_select}, + {&arrow_up,&arrow_down}, + selector_cb +}; + + +static void selector_cb(void) +{ + int i; + char text[MAXPATHLEN]; + int yoffset = 108; + + /* Initialize directory icon */ + gui_image dir_icon; + dir_icon.texture = gxTextureOpenPNG(Browser_dir_png,0); + dir_icon.w = dir_icon.texture->width; + dir_icon.h = dir_icon.texture->height; + dir_icon.x = 26; + dir_icon.y = (26 - dir_icon.h)/2; + + /* Initialize selection bar */ + gui_image bar_over; + bar_over.texture = gxTextureOpenPNG(Overlay_bar_png,0); + bar_over.w = bar_over.texture->width; + bar_over.h = bar_over.texture->height; + bar_over.x = 16; + bar_over.y = (26 - bar_over.h)/2; + + /* Draw browser array */ + gxDrawRectangle(15, 108, 358, 26, 127, (GXColor)BG_COLOR_1); + gxDrawRectangle(15, 134, 358, 26, 127, (GXColor)BG_COLOR_2); + gxDrawRectangle(15, 160, 358, 26, 127, (GXColor)BG_COLOR_1); + gxDrawRectangle(15, 186, 358, 26, 127, (GXColor)BG_COLOR_2); + gxDrawRectangle(15, 212, 358, 26, 127, (GXColor)BG_COLOR_1); + gxDrawRectangle(15, 238, 358, 26, 127, (GXColor)BG_COLOR_2); + gxDrawRectangle(15, 264, 358, 26, 127, (GXColor)BG_COLOR_1); + gxDrawRectangle(15, 290, 358, 26, 127, (GXColor)BG_COLOR_2); + gxDrawRectangle(15, 316, 358, 26, 127, (GXColor)BG_COLOR_1); + gxDrawRectangle(15, 342, 358, 26, 127, (GXColor)BG_COLOR_2); + + /* Draw Files list */ + for (i = offset; (i < (offset + 10)) && (i < maxfiles); i++) + { + if (i == selection) + { + /* selection bar */ + gxDrawTexture(bar_over.texture,bar_over.x,yoffset+bar_over.y,bar_over.w,bar_over.h,255); + + /* scrolling text */ + if ((string_offset/SCROLL_SPEED) >= strlen(filelist[i].filename)) + { + string_offset = 0; + } + + if (string_offset) + { + sprintf(text,"%s ",filelist[i].filename+string_offset/SCROLL_SPEED); + strncat(text, filelist[i].filename, string_offset/SCROLL_SPEED); + } + else + { + strcpy(text, filelist[i].filename); + } + + /* print text */ + if (filelist[i].flags) + { + /* directory icon */ + gxDrawTexture(dir_icon.texture,dir_icon.x,yoffset+dir_icon.y,dir_icon.w,dir_icon.h,255); + if (FONT_write(text,18,dir_icon.x+dir_icon.w+6,yoffset+22,bar_over.w-dir_icon.w-26,(GXColor)WHITE)) + { + /* text scrolling */ + string_offset ++; + } + } + else + { + if (FONT_write(text,18,dir_icon.x,yoffset+22,bar_over.w-20,(GXColor)WHITE)) + { + /* text scrolling */ + string_offset ++; + } + } + } + else + { + if (filelist[i].flags) + { + /* directory icon */ + gxDrawTexture(dir_icon.texture,dir_icon.x,yoffset+dir_icon.y,dir_icon.w,dir_icon.h,255); + FONT_write(filelist[i].filename,18,dir_icon.x+dir_icon.w+6,yoffset+22,bar_over.w-dir_icon.w-26,(GXColor)WHITE); + } + else + { + FONT_write(filelist[i].filename,18,dir_icon.x,yoffset+22,bar_over.w-20,(GXColor)WHITE); + } + } + + yoffset += 26; + } + + gxTextureClose(&bar_over.texture); + gxTextureClose(&dir_icon.texture); +} + + +/**************************************************************************** + * FileSelector + * + * Browse directories and select a file from the file listing + * return ROM size + * + ****************************************************************************/ +int FileSelector(int type) +{ + short p; + int i; + int old = -1; + char fname[MAXPATHLEN]; + FILE *snap; + gui_menu *m = &menu_selector; + +#ifdef HW_RVL + int x,y; + gui_butn *button; +#endif + + /* Background overlay */ + if (config.bg_overlay) + { + bg_filesel[1].state |= IMAGE_VISIBLE; + } + else + { + bg_filesel[1].state &= ~IMAGE_VISIBLE; + } + + /* Hide all cartridge labels */ + for (i=0; i select all cartridge type */ + for (i=0; i variable game types */ + if (type < 0) + { + /* hide all cartridge labels */ + for (i=0; i 0) && (fname[i] != '.')) i--; + if (i > 0) fname[i] = 0; + + /* add PNG file extension */ + strcat(fname, ".png"); + + /* try to load screenshot file */ + snap = fopen(fname, "rb"); + if (snap) + { + bg_filesel[8].texture = gxTextureOpenPNG(0,snap); + if (bg_filesel[8].texture) + { + bg_filesel[8].state |= IMAGE_VISIBLE; + } + fclose(snap); + } + } + } + + /* update helper */ + if (m->selected != -1) + { + /* out of focus */ + strcpy(action_select.comment,""); + } + else if (filelist[selection].flags) + { + /* this is a directory */ + strcpy(action_select.comment,"Open Directory"); + } + else + { + /* this is a ROM file */ + strcpy(action_select.comment,"Load File"); + } + + /* Draw menu*/ + GUI_DrawMenu(m); + +#ifdef HW_RVL + if (Shutdown) + { + gxTextureClose(&w_pointer); + GUI_DeleteMenu(m); + GUI_FadeOut(); + shutdown(); + SYS_ResetSystem(SYS_POWEROFF, 0, 0); + } + else if (m_input.ir.valid) + { + /* get cursor position */ + x = m_input.ir.x; + y = m_input.ir.y; + + /* draw wiimote pointer */ + gxDrawTextureRotate(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,m_input.ir.angle,255); + + /* ensure we are in the selectable area */ + if ((x < 380) && (y >= 108) && (y <= 368)) + { + /* find selected item */ + selection = (y - 108) / 26; + if (selection > 9) selection = 9; + selection += offset; + if (selection >= maxfiles) selection = old; + + /* reset selection */ + m->selected = -1; + } + else + { + /* disable selection */ + m->selected = m->max_buttons + 2; + + /* find selected button */ + for (i=0; i<2; i++) + { + button = m->arrows[i]; + if (button) + { + if (button->state & BUTTON_VISIBLE) + { + if ((x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) + { + m->selected = m->max_buttons + i; + break; + } + } + } + } + } + } + else + { + /* reset selection */ + m->selected = -1; + } +#endif + + /* copy EFB to XFB */ + gxSetScreen(); + + p = m_input.keys; + + /* highlight next item */ + if (p & PAD_BUTTON_DOWN) + { + selection++; + if (selection == maxfiles) + selection = offset = 0; + if ((selection - offset) >= 10) + offset += 10; + } + + /* highlight previous item */ + else if (p & PAD_BUTTON_UP) + { + selection--; + if (selection < 0) + { + selection = maxfiles - 1; + offset = maxfiles - 10; + } + if (selection < offset) + offset -= 10; + if (offset < 0) + offset = 0; + } + + /* go back one page */ + else if (p & (PAD_TRIGGER_L | PAD_BUTTON_LEFT)) + { + if (maxfiles >= 10) + { + selection -= 10; + if (selection < 0) + { + selection = offset = 0; + } + else if (selection < offset) + { + offset -= 10; + if (offset < 0) offset = 0; + } + } + } + + /* go forward one page */ + else if (p & (PAD_TRIGGER_R | PAD_BUTTON_RIGHT)) + { + if (maxfiles >= 10) + { + selection += 10; + if (selection > maxfiles - 1) + { + /* last page */ + selection = maxfiles - 1; + offset = maxfiles - 10; + } + else if (selection >= (offset + 10)) + { + /* next page */ + offset += 10; + if (offset > (maxfiles - 10)) offset = maxfiles - 10; + } + } + } + + /* quit */ + else if (p & PAD_TRIGGER_Z) + { + GUI_DeleteMenu(m); + return 0; + } + + /* previous directory */ + else if (p & PAD_BUTTON_B) + { + string_offset = 0; + + /* update browser directory (and get current folder)*/ + if (UpdateDirectory(1, prev_folder)) + { + /* get directory entries */ + maxfiles = ParseDirectory(); + + /* clear selection by default */ + selection = offset = 0; + old = -1; + + /* select previous directory */ + for (i=0; i= (offset + 10)) + { + offset += 10; + if (offset > (maxfiles - 10)) offset = maxfiles - 10; + } + break; + } + } + } + else + { + /* exit */ + GUI_DeleteMenu(m); + return 0; + } + } + + /* open selected file or directory */ + else if (p & PAD_BUTTON_A) + { + string_offset = 0; + + /* ensure we are in focus area */ + if (m->selected < m->max_buttons) + { + if (filelist[selection].flags) + { + /* get new directory */ + UpdateDirectory(0, filelist[selection].filename); + + /* get directory entries */ + maxfiles = ParseDirectory(); + + /* clear selection by default */ + selection = offset = 0; + old = -1; + } + else + { + /* load ROM file from device */ + int ret = LoadFile(selection); + + /* exit menu */ + GUI_DeleteMenu(m); + + /* return ROM size (or zero if an error occured) */ + return ret; + } + } + +#ifdef HW_RVL + /* arrow buttons selected */ + else if (m->selected == m->max_buttons) + { + /* up arrow */ + selection--; + if (selection < 0) + { + selection = maxfiles - 1; + offset = selection - 10 + 1; + } + if (selection < offset) offset -= 10; + if (offset < 0) offset = 0; + } + else if (m->selected == (m->max_buttons+1)) + { + /* down arrow */ + selection++; + if (selection == maxfiles) + selection = offset = 0; + if ((selection - offset) >= 10) + offset += 10; + } +#endif + } + } +} + +void ClearSelector(u32 max) +{ + maxfiles = max; + offset = 0; + selection = 0; +} diff --git a/genplus-gx/gx/gui/filesel.h b/genplus-gx/gx/gui/filesel.h new file mode 100644 index 0000000000..213e304f69 --- /dev/null +++ b/genplus-gx/gx/gui/filesel.h @@ -0,0 +1,58 @@ +/* + * filesel.c + * + * ROM File Browser + * + * Copyright Eke-Eke (2009-2013) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _FILESEL_H +#define _FILESEL_H + +#define MAXJOLIET 256 +#define MAXFILES 1000 + +/* Filelist structure */ +typedef struct +{ + u8 flags; + char filename[MAXJOLIET]; +}FILEENTRIES; + +/* Globals */ +extern int FileSelector(int type); +extern void ClearSelector(u32 max); +extern FILEENTRIES filelist[MAXFILES]; + +#endif diff --git a/genplus-gx/gx/gui/font.c b/genplus-gx/gx/gui/font.c new file mode 100644 index 0000000000..36582147e1 --- /dev/null +++ b/genplus-gx/gx/gui/font.c @@ -0,0 +1,400 @@ +/***************************************************************************** + * font.c + * + * IPL font engine (using GX rendering) + * + * Copyright Eke-Eke (2009-2013) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "font.h" + +#define _SHIFTR(v, s, w) \ + ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1))) + +typedef struct _yay0header { + unsigned int id ATTRIBUTE_PACKED; + unsigned int dec_size ATTRIBUTE_PACKED; + unsigned int links_offset ATTRIBUTE_PACKED; + unsigned int chunks_offset ATTRIBUTE_PACKED; +} yay0header; + +static u8 *fontImage; +static u8 *fontTexture; +static void *ipl_fontarea; +static sys_fontheader *fontHeader; +static u8 font_size[256]; + +#ifndef HW_RVL + +/* disable Qoob Modchip before IPL access (emukiddid) */ +static void ipl_set_config(unsigned char c) +{ + volatile unsigned long* exi = (volatile unsigned long*)0xCC006800; + unsigned long val,addr; + addr=0xc0000000; + val = c << 24; + exi[0] = ((((exi[0]) & 0x405) | 256) | 48); //select IPL + //write addr of IPL + exi[0 * 5 + 4] = addr; + exi[0 * 5 + 3] = ((4 - 1) << 4) | (1 << 2) | 1; + while (exi[0 * 5 + 3] & 1); + //write the ipl we want to send + exi[0 * 5 + 4] = val; + exi[0 * 5 + 3] = ((4 - 1) << 4) | (1 << 2) | 1; + while (exi[0 * 5 + 3] & 1); + exi[0] &= 0x405; //deselect IPL +} + +#endif + +static void decode_szp(void *src,void *dest) +{ + u32 i,k,link; + u8 *dest8,*tmp; + u32 loff,coff,roff; + u32 size,cnt,cmask,bcnt; + yay0header *header; + + dest8 = (u8*)dest; + header = (yay0header*)src; + size = header->dec_size; + loff = header->links_offset; + coff = header->chunks_offset; + + roff = sizeof(yay0header); + cmask = 0; + cnt = 0; + bcnt = 0; + + do { + if(!bcnt) { + cmask = *(u32*)(src+roff); + roff += 4; + bcnt = 32; + } + + if(cmask&0x80000000) { + dest8[cnt++] = *(u8*)(src+coff); + coff++; + } else { + link = *(u16*)(src+loff); + loff += 2; + + tmp = dest8+(cnt-(link&0x0fff)-1); + k = link>>12; + if(k==0) { + k = (*(u8*)(src+coff))+18; + coff++; + } else k += 2; + + for(i=0;isheet_format==0x0000) { + cnt = (sys_fontdata->sheet_fullsize/2)-1; + + while(cnt>=0) { + idx = _SHIFTR(src[cnt],6,2); + val1 = data[idx]; + + idx = _SHIFTR(src[cnt],4,2); + val2 = data[idx]; + + dest[(cnt<<1)+0] =((val1&0xf0)|(val2&0x0f)); + + idx = _SHIFTR(src[cnt],2,2); + val1 = data[idx]; + + idx = _SHIFTR(src[cnt],0,2); + val2 = data[idx]; + + dest[(cnt<<1)+1] =((val1&0xf0)|(val2&0x0f)); + + cnt--; + } + } + DCStoreRange(dest,sys_fontdata->sheet_fullsize); +} + +static void GetFontTexel(s32 c,void *image,s32 pos,s32 stride) +{ + u32 sheets,rem; + u32 xoff,yoff; + u32 xpos,ypos; + u8 *img_start; + u8 *ptr1,*ptr2; + sys_fontheader *sys_fontdata = fontHeader; + + if(cfirst_char || c>sys_fontdata->last_char) c = sys_fontdata->inval_char; + else c -= sys_fontdata->first_char; + + sheets = sys_fontdata->sheet_column*sys_fontdata->sheet_row; + rem = c%sheets; + sheets = c/sheets; + xoff = (rem%sys_fontdata->sheet_column)*sys_fontdata->cell_width; + yoff = (rem/sys_fontdata->sheet_column)*sys_fontdata->cell_height; + img_start = fontImage+(sys_fontdata->sheet_size*sheets); + + ypos = 0; + while(yposcell_height) { + xpos = 0; + while(xposcell_width) { + ptr1 = img_start+(((sys_fontdata->sheet_width/8)<<5)*((ypos+yoff)/8)); + ptr1 = ptr1+(((xpos+xoff)/8)<<5); + ptr1 = ptr1+(((ypos+yoff)%8)<<2); + ptr1 = ptr1+(((xpos+xoff)%8)/2); + + ptr2 = image+((ypos/8)*(((stride<<1)/8)<<5)); + ptr2 = ptr2+(((xpos+pos)/8)<<5); + ptr2 = ptr2+(((xpos+pos)%8)/2); + ptr2 = ptr2+((ypos%8)<<2); + + *ptr2 = *ptr1; + + xpos += 2; + } + ypos++; + } +} + +static void DrawChar(unsigned char c, int xpos, int ypos, int size, GXColor color) +{ + /* reintialize texture object */ + GXTexObj texobj; + GX_InitTexObj(&texobj, fontTexture, fontHeader->cell_width, fontHeader->cell_height, GX_TF_I4, GX_CLAMP, GX_CLAMP, GX_FALSE); + GX_LoadTexObj(&texobj, GX_TEXMAP0); + + /* reinitialize font texture data */ + memset(fontTexture,0,fontHeader->cell_width * fontHeader->cell_height / 2); + GetFontTexel(c,fontTexture,0,fontHeader->cell_width/2); + DCFlushRange(fontTexture, fontHeader->cell_width * fontHeader->cell_height / 2); + GX_InvalidateTexAll(); + + /* adjust texture width */ + s32 width = (fontHeader->cell_width * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth); + + /* adjust texture height */ + size = (size * vmode->efbHeight) / 480; + + /* GX rendering */ + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position2s16(xpos, ypos - size); + GX_Color4u8(color.r, color.g, color.b, 0xff); + GX_TexCoord2f32(0.0, 0.0); + GX_Position2s16(xpos + width, ypos - size); + GX_Color4u8(color.r, color.g, color.b, 0xff); + GX_TexCoord2f32(1.0, 0.0); + GX_Position2s16(xpos + width, ypos); + GX_Color4u8(color.r, color.g, color.b, 0xff); + GX_TexCoord2f32(1.0, 1.0); + GX_Position2s16(xpos, ypos); + GX_Color4u8(color.r, color.g, color.b, 0xff); + GX_TexCoord2f32(0.0, 1.0); + GX_End(); + GX_DrawDone(); +} + +/**************************************************************************** + * IPL font support + * + ****************************************************************************/ +extern void __SYS_ReadROM(void *buf,u32 len,u32 offset); + +int FONT_Init(void) +{ +#ifndef HW_RVL + /* --- Game Cube --- disable Qoob before accessing IPL */ + ipl_set_config(6); +#endif + + /* read IPL font (ASCII) from Mask ROM */ + ipl_fontarea = memalign(32,131360); + if (!ipl_fontarea) + return 0; + memset(ipl_fontarea,0,131360); + __SYS_ReadROM(ipl_fontarea+119072,12288,0x1FCF00); + + /* YAY0 decompression */ + decode_szp(ipl_fontarea+119072,ipl_fontarea); + + /* retrieve IPL font data */ + fontHeader = (sys_fontheader*)ipl_fontarea; + fontImage = (u8*)((((u32)ipl_fontarea+fontHeader->sheet_image)+31)&~31); + + /* expand to I4 format */ + expand_font((u8*)ipl_fontarea+fontHeader->sheet_image,fontImage); + + /* character width table */ + int i,c; + for (i=0; i<256; ++i) + { + if ((i < fontHeader->first_char) || (i > fontHeader->last_char)) + c = fontHeader->inval_char; + else + c = i - fontHeader->first_char; + + font_size[i] = ((u8*)fontHeader)[fontHeader->width_table + c]; + } + + /* initialize texture data */ + fontTexture = memalign(32, fontHeader->cell_width * fontHeader->cell_height / 2); + if (!fontTexture) + { + free(ipl_fontarea); + return 0; + } + + return 1; +} + +void FONT_Shutdown(void) +{ + if (fontHeader) + free(ipl_fontarea); + if (fontTexture) + free(fontTexture); +} + +int FONT_write(char *string, int size, int x, int y, int max_width, GXColor color) +{ + int w, ox; + + x -= (vmode->fbWidth / 2); + y -= (vmode->efbHeight / 2); + + ox = x; + + while (*string) + { + if (*string == '\n') + { + x = ox; + y += size; + } + else + { + w = (font_size[(u8)*string] * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth); + if ((x + w) > (ox + max_width)) return strlen(string); + DrawChar(*string, x, y, size,color); + x += w; + } + string++; + } + + return 0; +} + +int FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor color) +{ + int x; + int i = 0; + int w = 0; + + while (string[i] && (string[i] != '\n')) + { + w += (font_size[(u8)string[i++]] * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth); + } + + if ((x1 + w) > x2) w = x2 - x1; + x = x1 + (x2 - x1 - w - vmode->fbWidth) / 2; + x2 -= (vmode->fbWidth / 2); + y -= (vmode->efbHeight / 2); + + while (*string && (*string != '\n')) + { + w = (font_size[(u8)*string] * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth); + if ((x + w) > x2) return strlen(string); + DrawChar(*string, x, y, size,color); + x += w; + string++; + } + + if (*string == '\n') + { + string++; + return FONT_writeCenter(string, size, x1, x2 + (vmode->fbWidth / 2), y + size + (vmode->efbHeight / 2), color); + } + + return 0; +} + +int FONT_alignRight(char *string, int size, int x, int y, GXColor color) +{ + int ox; + int i = 0; + int w = 0; + + while (string[i] && (string[i] != '\n')) + { + w += (font_size[(u8)string[i++]] * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth); + } + + x -= (vmode->fbWidth / 2); + y -= (vmode->efbHeight / 2); + + ox = x; + x -= w; + + while (*string && (*string != '\n')) + { + w = (font_size[(u8)*string] * size * vmode->fbWidth) / (fontHeader->cell_height * vmode->viWidth); + if ((x + w) > ox) return strlen(string); + DrawChar(*string, x, y, size,color); + x += w; + string++; + } + + if (*string == '\n') + { + string++; + return FONT_alignRight(string, size, ox + (vmode->fbWidth / 2), y + size + (vmode->efbHeight / 2), color); + } + + return 0; +} diff --git a/genplus-gx/gx/gui/font.h b/genplus-gx/gx/gui/font.h new file mode 100644 index 0000000000..8f516558af --- /dev/null +++ b/genplus-gx/gx/gui/font.h @@ -0,0 +1,49 @@ +/***************************************************************************** + * font.c + * + * IPL font engine (using GX rendering) + * + * Copyright Eke-Eke (2009-2013) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _FONT_H +#define _FONT_H + +extern int FONT_Init(void); +extern void FONT_Shutdown(void); +extern int FONT_write(char *string, int size, int x, int y, int max_width, GXColor color); +extern int FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor color); +extern int FONT_alignRight(char *string, int size, int x, int y, GXColor color); + +#endif diff --git a/genplus-gx/gx/gui/gui.c b/genplus-gx/gx/gui/gui.c new file mode 100644 index 0000000000..21fc49065e --- /dev/null +++ b/genplus-gx/gx/gui/gui.c @@ -0,0 +1,1968 @@ +/**************************************************************************** + * gui.c + * + * generic GUI Engine (using GX rendering) + * + * Copyright Eke-Eke (2009-2010) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "gui.h" +#include "font.h" + +#ifdef HW_RVL +gx_texture *w_pointer; +#endif + +u8 SILENT = 0; + +/* message box */ +static gui_message message_box; +static lwp_t msgboxthread; + +/* background color (black) */ +static const GXColor bg_color = {0x00,0x00,0x00,0xff}; + +/****************************************************************************/ +/* Generic GUI routines */ +/*****************************************************************************/ + +/* Allocate Menu texture images data */ +void GUI_InitMenu(gui_menu *menu) +{ + int i; + gui_item *item; + gui_butn *button; + gui_image *image; + + /* background elements */ + for (i=0; imax_images; i++) + { + image = &menu->bg_images[i]; + image->texture = gxTextureOpenPNG(image->data,0); + } + + for (i=0; i<2; i++) + { + /* key helpers */ + item = menu->helpers[i]; + if (item) + item->texture = gxTextureOpenPNG(item->data,0); + + /* arrows */ + button = menu->arrows[i]; + if (button) + { + if (!button->data->texture[0]) + button->data->texture[0] = gxTextureOpenPNG(button->data->image[0],0); + if (!button->data->texture[1]) + button->data->texture[1] = gxTextureOpenPNG(button->data->image[1],0); + + /* initial state */ + button->state &= ~BUTTON_VISIBLE; + if (((i==0) && (menu->offset != 0)) || ((i==1) && (menu->offset + menu->max_buttons) < menu->max_items)) + button->state |= BUTTON_VISIBLE; + } + } + + /* menu buttons */ + for (i=0; imax_buttons; i++) + { + button = &menu->buttons[i]; + if (button->data) + { + if (!button->data->texture[0]) + button->data->texture[0] = gxTextureOpenPNG(button->data->image[0],0); + if (!button->data->texture[1]) + button->data->texture[1] = gxTextureOpenPNG(button->data->image[1],0); + } + } + + /* menu items */ + for (i=0; imax_items; i++) + { + item = &menu->items[i]; + if (item->data) + item->texture = gxTextureOpenPNG(item->data,0); + } + + /* update message box */ + message_box.parent = menu; +} + +/* Release Menu allocated memory */ +void GUI_DeleteMenu(gui_menu *menu) +{ + int i; + gui_butn *button; + gui_item *item; + gui_image *image; + + /* background elements */ + for (i=0; imax_images; i++) + { + image = &menu->bg_images[i]; + gxTextureClose(&image->texture); + } + + for (i=0; i<2; i++) + { + /* key helpers */ + item = menu->helpers[i]; + if (item) + gxTextureClose(&item->texture); + + /* arrows */ + button = menu->arrows[i]; + if (button) + { + gxTextureClose(&button->data->texture[0]); + gxTextureClose(&button->data->texture[1]); + } + } + + /* menu buttons */ + for (i=0; imax_buttons; i++) + { + button = &menu->buttons[i]; + if (button->data) + { + gxTextureClose(&button->data->texture[0]); + gxTextureClose(&button->data->texture[1]); + } + } + + /* menu items */ + for (i=0; imax_items; i++) + { + item = &menu->items[i]; + gxTextureClose(&item->texture); + } +} + +extern void gxSnapshot(void); + +/* Draw Menu */ +void GUI_DrawMenu(gui_menu *menu) +{ + int i; + gui_item *item; + gui_butn *button; + gui_image *image; + + /* background color */ + if (menu->screenshot) + { + gxClearScreen((GXColor)BLACK); + gxDrawScreenshot(menu->screenshot); + } + else + { + gxClearScreen(bg_color); + } + + /* background elements */ + for (i=0; imax_images; i++) + { + image = &menu->bg_images[i]; + if (image->state & IMAGE_VISIBLE) + { + if (image->state & IMAGE_REPEAT) + gxDrawTextureRepeat(image->texture,image->x,image->y,image->w,image->h,image->alpha); + else + gxDrawTexture(image->texture,image->x,image->y,image->w,image->h,image->alpha); + } + } + + /* menu title */ + FONT_write(menu->title, 22,10,56,640,(GXColor)WHITE); + + /* draw buttons + items */ + for (i=0; imax_buttons; i++) + { + button = &menu->buttons[i]; + + if (button->state & BUTTON_VISIBLE) + { + /* item select (text or image) */ + item = (menu->items) ? (&menu->items[menu->offset + i]) : NULL; + + /* draw button + items */ + if ((i == menu->selected) || (button->state & BUTTON_SELECTED)) + { + if (button->data) + gxDrawTexture(button->data->texture[1],button->x-4,button->y-4,button->w+8,button->h+8,255); + + if (item) + { + if (item->texture) + { + gxDrawTexture(item->texture, item->x-4,item->y-4,item->w+8,item->h+8,255); + FONT_writeCenter(item->text,18,button->x+4,item->x-4,button->y+(button->h - 36)/2+18,(GXColor)DARK_GREY); + } + else + { + FONT_writeCenter(item->text,18,item->x-4,item->x+item->w+4,button->y+(button->h-18)/2+18,(GXColor)DARK_GREY); + } + } + } + else + { + if (button->data) + gxDrawTexture(button->data->texture[0],button->x,button->y,button->w, button->h,255); + + if (item) + { + if (item->texture) + { + gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); + FONT_writeCenter(item->text,16,button->x+8,item->x,button->y+(button->h - 32)/2+16,(GXColor)DARK_GREY); + } + else + { + FONT_writeCenter(item->text,16,item->x,item->x+item->w,button->y+(button->h - 16)/2+16,(GXColor)DARK_GREY); + } + } + } + } + } + + /* draw arrow */ + for (i=0; i<2; i++) + { + button = menu->arrows[i]; + if (button) + { + if (button->state & BUTTON_VISIBLE) + { + if (menu->selected == (menu->max_buttons + i)) + gxDrawTexture(button->data->texture[1],button->x-2,button->y-2,button->w+4,button->h+4,255); + else + gxDrawTexture(button->data->texture[0],button->x,button->y,button->w, button->h,255); + } + } + } + + /* left comment */ + item = menu->helpers[0]; + if (item) + { + if (item->data && strlen(item->comment)) + { + gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); + FONT_write(item->comment,16,item->x+item->w+6,item->y+(item->h-16)/2 + 16,640,(GXColor)WHITE); + } + } + + /* right comment */ + item = menu->helpers[1]; + if (item) + { + if (item->data && strlen(item->comment)) + { + gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); + FONT_alignRight(item->comment,16,item->x-6,item->y+(item->h-16)/2+16,(GXColor)WHITE); + } + } + + if (menu->cb) + menu->cb(); +} + +/* Draw Menu with transitions effects */ +void GUI_DrawMenuFX(gui_menu *menu, u8 speed, u8 out) +{ + int i,temp,xoffset,yoffset; + int max_offset = 0; + u8 item_alpha = 255; + GXColor text_color = DARK_GREY; + gui_item *item; + gui_butn *button; + gui_image *image; + + /* find maximal offset */ + for (i=0; imax_images; i++) + { + image = &menu->bg_images[i]; + + if (image->state & IMAGE_SLIDE_LEFT) + { + temp = image->x + image->w; + if (max_offset < temp) + max_offset = temp; + } + else if (image->state & IMAGE_SLIDE_RIGHT) + { + temp = 640 - image->x; + if (max_offset < temp) + max_offset = temp; + } + + if (image->state & IMAGE_SLIDE_TOP) + { + temp = image->y + image->h; + if (max_offset < temp) + max_offset = temp; + } + else if (image->state & IMAGE_SLIDE_BOTTOM) + { + temp = 480 - image->y; + if (max_offset < temp) + max_offset = temp; + } + } + + temp = max_offset; + + /* Alpha steps */ + int alpha = 0; + int alpha_step = (255 * speed) / max_offset; + if (out) + { + alpha = 255; + alpha_step = -alpha_step; + } + + /* Let's loop until final position has been reached */ + while (temp > 0) + { + /* background color */ + if (menu->screenshot) + { + gxClearScreen((GXColor)BLACK); + if (alpha >= menu->screenshot) + gxDrawScreenshot(menu->screenshot); + else + gxDrawScreenshot(255 - alpha); + } + else + { + gxClearScreen(bg_color); + } + + /* background images */ + for (i=0; imax_images; i++) + { + image = &menu->bg_images[i]; + + /* X offset */ + if (image->state & IMAGE_SLIDE_LEFT) + xoffset = out ? (temp - max_offset) : (-temp); + else if (image->state & IMAGE_SLIDE_RIGHT) + xoffset = out ? (max_offset - temp) : (temp); + else + xoffset = 0; + + /* Y offset */ + if (image->state & IMAGE_SLIDE_TOP) + yoffset = out ? (temp - max_offset) : (-temp); + else if (image->state & IMAGE_SLIDE_BOTTOM) + yoffset = out ? (max_offset - temp) : (temp); + else + yoffset = 0; + + /* draw image */ + if ((image->state & IMAGE_FADE) && ((out && (image->alpha > alpha)) || (!out && (image->alpha < alpha)))) + { + /* FADE In-Out */ + if (image->state & IMAGE_VISIBLE) + { + if (image->state & IMAGE_REPEAT) + gxDrawTextureRepeat(image->texture,image->x+xoffset,image->y+yoffset,image->w,image->h,alpha); + else + gxDrawTexture(image->texture,image->x+xoffset,image->y+yoffset,image->w,image->h,alpha); + } + } + else + { + if (image->state & IMAGE_VISIBLE) + { + if (image->state & IMAGE_REPEAT) + gxDrawTextureRepeat(image->texture,image->x+xoffset,image->y+yoffset,image->w,image->h,image->alpha); + else + gxDrawTexture(image->texture,image->x+xoffset,image->y+yoffset,image->w,image->h,image->alpha); + } + } + } + + /* menu title */ + if ((menu->bg_images[2].state & IMAGE_SLIDE_TOP) || (menu->bg_images[3].state & IMAGE_SLIDE_TOP)) + FONT_write(menu->title, 22,10,out ? (56 + temp - max_offset) : (56 - temp),640,(GXColor)WHITE); + else + FONT_write(menu->title, 22,10,56,640,(GXColor)WHITE); + + /* draw buttons + items */ + for (i=0; imax_buttons; i++) + { + button = &menu->buttons[i]; + + if (button->state & BUTTON_VISIBLE) + { + /* X offset */ + if (button->state & BUTTON_SLIDE_LEFT) + xoffset = out ? (temp - max_offset) : (-temp); + else if (button->state & BUTTON_SLIDE_RIGHT) + xoffset = out ? (max_offset - temp) : (temp); + else + xoffset = 0; + + /* Y offset */ + if (button->state & BUTTON_SLIDE_TOP) + yoffset = out ? (temp - max_offset) : (-temp); + else if (button->state & BUTTON_SLIDE_BOTTOM) + yoffset = out ? (max_offset - temp) : (temp); + else + yoffset = 0; + + /* Alpha transparency */ + if (button->state & BUTTON_FADE) + { + item_alpha = alpha; + text_color.a = alpha; + } + else + { + item_alpha = 255; + text_color.a = 255; + } + + /* item select (text or image) */ + item = (menu->items) ? (&menu->items[menu->offset + i]) : NULL; + + /* draw button + items */ + if ((i == menu->selected) || (button->state & BUTTON_SELECTED)) + { + if (button->data) + gxDrawTexture(button->data->texture[1],button->x+xoffset-4,button->y+yoffset-4,button->w+8,button->h+8,item_alpha); + + if (item) + { + if (item->texture) + { + gxDrawTexture(item->texture, item->x+xoffset-4,item->y+yoffset-4,item->w+8,item->h+8,item_alpha); + FONT_writeCenter(item->text,18,button->x+xoffset+4,item->x+xoffset-4,button->y+yoffset+(button->h - 36)/2+18,text_color); + } + else + { + FONT_writeCenter(item->text,18,item->x+xoffset+2,item->x+item->w+xoffset+2,button->y+yoffset+(button->h-18)/2+18,text_color); + } + } + } + else + { + if (button->data) + gxDrawTexture(button->data->texture[0],button->x+xoffset,button->y+yoffset,button->w, button->h,item_alpha); + + if (item) + { + if (item->texture) + { + gxDrawTexture(item->texture,item->x+xoffset,item->y+yoffset,item->w,item->h,item_alpha); + FONT_writeCenter(item->text,16,button->x+xoffset+8,item->x+xoffset,button->y+yoffset+(button->h - 32)/2+16,text_color); + } + else + { + FONT_writeCenter(item->text,16,item->x+xoffset,item->x+item->w+xoffset,button->y+yoffset+(button->h - 16)/2+16,text_color); + } + } + } + } + } + + /* draw arrow */ + for (i=0; i<2; i++) + { + button = menu->arrows[i]; + if (button) + { + if (button->state & BUTTON_VISIBLE) + { + if (menu->selected == (menu->max_buttons + i)) + gxDrawTexture(button->data->texture[1],button->x-2,button->y-2,button->w+4,button->h+4,255); + else + gxDrawTexture(button->data->texture[0],button->x,button->y,button->w, button->h,255); + } + } + } + + if (!(menu->bg_images[3].state & IMAGE_SLIDE_BOTTOM) && !(menu->bg_images[4].state & IMAGE_SLIDE_BOTTOM)) + { + /* left comment */ + item = menu->helpers[0]; + if (item) + { + if (item->data && strlen(item->comment)) + { + gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); + FONT_write(item->comment,16,item->x+item->w+6,item->y+(item->h-16)/2 + 16,640,(GXColor)WHITE); + } + } + + /* right comment */ + item = menu->helpers[1]; + if (item) + { + if (item->data && strlen(item->comment)) + { + gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); + FONT_alignRight(item->comment,16,item->x-6,item->y+(item->h-16)/2+16,(GXColor)WHITE); + } + } + } + + if (menu->cb) + menu->cb(); + + /* update offset */ + temp -= speed; + + /* update alpha */ + alpha += alpha_step; + if (alpha > 255) + alpha = 255; + else if (alpha < 0) + alpha = 0; + + + /* copy EFB to XFB */ + gxSetScreen(); + } + + /* final position */ + if (!out) + { + GUI_DrawMenu(menu); + gxSetScreen(); + } + else if (menu->screenshot) + { + gxClearScreen((GXColor)BLACK); + gxDrawScreenshot(255); + gxSetScreen(); + } +} + +/* Basic menu title slide effect */ +void GUI_SlideMenuTitle(gui_menu *m, int title_offset) +{ +#ifdef HW_RVL + gui_butn *button; + int i,x,y; +#endif + + char title[64]; + strcpy(title,m->title); + + while (title_offset > 0) + { + /* update title */ + strcpy(m->title,title+title_offset); + m->title[strlen(title)-title_offset-1] = 0; + + /* draw menu */ + GUI_DrawMenu(m); + +#ifdef HW_RVL + /* keep pointer active */ + if (m_input.ir.valid) + { + /* get cursor position */ + x = m_input.ir.x; + y = m_input.ir.y; + + /* draw wiimote pointer */ + gxDrawTextureRotate(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,m_input.ir.angle,255); + + /* check for valid buttons */ + m->selected = m->max_buttons + 2; + for (i=0; imax_buttons; i++) + { + button = &m->buttons[i]; + if ((button->state & BUTTON_ACTIVE)&&(x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) + { + m->selected = i; + break; + } + } + + for (i=0; i<2; i++) + { + button = m->arrows[i]; + if (button) + { + if (button->state & BUTTON_VISIBLE) + { + if ((x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) + { + m->selected = m->max_buttons + i; + break; + } + } + } + } + } +#endif + gxSetScreen(); + usleep(6000); + title_offset--; + } + strcpy(m->title,title); +} + +/* Update current menu */ +int GUI_UpdateMenu(gui_menu *menu) +{ + u16 p; + int ret = 0; + int selected = menu->selected; + int max_items = menu->max_items; + int max_buttons = menu->max_buttons; + gui_butn *button; + +#ifdef HW_RVL + if (Shutdown) + { + GUI_DeleteMenu(menu); + GUI_FadeOut(); + shutdown(); + SYS_ResetSystem(SYS_POWEROFF, 0, 0); + } + else if (m_input.ir.valid) + { + /* get cursor position */ + int x = m_input.ir.x; + int y = m_input.ir.y; + + /* draw wiimote pointer */ + gxDrawTextureRotate(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,m_input.ir.angle,255); + + /* check for valid buttons */ + selected = max_buttons + 2; + int i; + for (i=0; ibuttons[i]; + if ((button->state & BUTTON_ACTIVE) && (button->state & BUTTON_VISIBLE)) + { + if((x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) + { + selected = i; + break; + } + } + } + + for (i=0; i<2; i++) + { + button = menu->arrows[i]; + if (button) + { + if ((button->state & BUTTON_ACTIVE) && (button->state & BUTTON_VISIBLE)) + { + if ((x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) + { + selected = max_buttons + i; + break; + } + } + } + } + } + else + { + /* reinitialize selection */ + if (selected >= menu->max_buttons) + { + selected = 0; + while ((selected < (menu->max_buttons + 2)) && + (!(menu->buttons[selected].state & BUTTON_ACTIVE) || + !(menu->buttons[selected].state & BUTTON_VISIBLE))) + selected++; + } + } +#endif + + /* update screen */ + gxSetScreen(); + + /* update menu */ + p = m_input.keys; + + if (selected < max_buttons) + { + button = &menu->buttons[selected]; + if (p & PAD_BUTTON_UP) + { + selected -= button->shift[0]; + if (selected < 0) + { + selected = 0; + if (menu->offset) + menu->offset --; + } + } + else if (p & PAD_BUTTON_DOWN) + { + selected += button->shift[1]; + if (selected >= max_buttons) + { + selected = max_buttons - 1; + if ((menu->offset + selected) < (max_items - 1)) + menu->offset ++; + } + } + else if (p & PAD_BUTTON_LEFT) + { + selected -= button->shift[2]; + if (selected < 0) + { + selected = 0; + if (menu->offset) + menu->offset --; + } + } + else if (p & PAD_BUTTON_RIGHT) + { + selected += button->shift[3]; + if (selected >= max_buttons) + { + selected = max_buttons - 1; + if ((menu->offset + selected) < (max_items - 1)) + menu->offset ++; + } + } + } + + if (p & PAD_BUTTON_A) + { + if (selected < max_buttons) + ret = 1; /* menu clicked */ + else if (selected == max_buttons) + menu->offset --; /* up arrow */ + else if (selected == (max_buttons+1)) + menu->offset ++; /* down arrow */ + } + else if ((p & PAD_BUTTON_B) || (p & PAD_TRIGGER_Z)) + { + /* quit menu */ + ret = -1; + } + + /* selected item has changed ? */ + if (menu->selected != selected) + { + if (selected < max_buttons) + { + /* sound fx */ + button = &menu->buttons[selected]; + if (button->state & BUTTON_OVER_SFX) + { + ASND_SetVoice(ASND_GetFirstUnusedVoice(),VOICE_MONO_16BIT,22050,0,(u8 *)button_over_pcm,button_over_pcm_size, + ((int)config.sfx_volume * 255) / 100,((int)config.sfx_volume * 255) / 100,NULL); + } + } + else if (selected < (max_buttons + 2)) + { + /* sound fx */ + button = menu->arrows[selected-max_buttons]; + if (button->state & BUTTON_OVER_SFX) + { + ASND_SetVoice(ASND_GetFirstUnusedVoice(),VOICE_MONO_16BIT,22050,0,(u8 *)button_over_pcm,button_over_pcm_size, + ((int)config.sfx_volume * 255) / 100,((int)config.sfx_volume * 255) / 100,NULL); + } + } + + /* update selection */ + menu->selected = selected; + } + + /* update helper comment */ + if (menu->helpers[1]) + { + if ((menu->offset + selected) < max_items) + { + gui_item *item = &menu->items[menu->offset + selected]; + strcpy(menu->helpers[1]->comment,item->comment); + } + else + { + strcpy(menu->helpers[1]->comment,""); + } + } + + if (ret > 0) + { + if (selected < max_buttons) + { + /* sound fx */ + button = &menu->buttons[selected]; + if (button->state & BUTTON_SELECT_SFX) + { + ASND_SetVoice(ASND_GetFirstUnusedVoice(),VOICE_MONO_16BIT,22050,0,(u8 *)button_select_pcm,button_select_pcm_size, + ((int)config.sfx_volume * 255) / 100,((int)config.sfx_volume * 255) / 100,NULL); + } + } + } + + return ret; +} + +/* Generic routine to render & update menus */ +int GUI_RunMenu(gui_menu *menu) +{ + int update = 0; + + /* update menu */ + while (!update) + { + GUI_DrawMenu(menu); + update = GUI_UpdateMenu(menu); + + /* update arrows buttons status (items list) */ + if (menu->arrows[0]) + { + if (menu->offset > 0) + menu->arrows[0]->state |= BUTTON_VISIBLE; + else + menu->arrows[0]->state &= ~BUTTON_VISIBLE; + } + + if (menu->arrows[1]) + { + if ((menu->offset + menu->max_buttons) < menu->max_items) + menu->arrows[1]->state |= BUTTON_VISIBLE; + else + menu->arrows[1]->state &= ~BUTTON_VISIBLE; + } + } + + if (update == 2) + return (-2-menu->offset-menu->selected); + else if (update == 1) + return (menu->offset + menu->selected); + else + return -1; + } + +/* Text Window */ +void GUI_TextWindow(gui_menu *parent, char *title, char items[][64], u8 nb_items, u8 fontsize) +{ + int i, quit = 0; + +#ifdef HW_RVL + int x,y; +#endif + + /* initialize window */ + gx_texture *window = gxTextureOpenPNG(Frame_s1_png,0); + gx_texture *top = gxTextureOpenPNG(Frame_s1_title_png,0); + + /* window position */ + int xwindow = (640 - window->width) /2; + int ywindow = (480 - window->height)/2; + + /* text position */ + int ypos = ywindow + top->height + (window->height - top->height - fontsize*nb_items) / 2 + fontsize/2; + + /* disable helper comment */ + const u8 *data = NULL; + if (parent->helpers[1]) + { + data = parent->helpers[1]->data; + parent->helpers[1]->data = NULL; + } + + /* slide in */ + int yoffset = ywindow + window->height; + while (yoffset > 0) + { + /* draw parent menu */ + GUI_DrawMenu(parent); + + /* draw window */ + gxDrawTexture(window,xwindow,ywindow-yoffset,window->width,window->height,230); + gxDrawTexture(top,xwindow,ywindow-yoffset,top->width,top->height,255); + + /* draw title */ + FONT_writeCenter(title,20,xwindow,xwindow+window->width,ywindow+(top->height-20)/2+20-yoffset,(GXColor)WHITE); + + /* draw text */ + for (i=0; iwidth,ypos+i*fontsize-yoffset,(GXColor)WHITE); + + /* update display */ + gxSetScreen(); + + /* slide speed */ + yoffset -= 60; + } + + /* draw menu + text window */ + while (quit == 0) + { + /* draw parent menu */ + GUI_DrawMenu(parent); + + /* draw window */ + gxDrawTexture(window,xwindow,ywindow,window->width,window->height,230); + gxDrawTexture(top,xwindow,ywindow,top->width,top->height,255); + + /* draw title */ + FONT_writeCenter(title,20,xwindow,xwindow+window->width,ywindow+(top->height-20)/2+20,(GXColor)WHITE); + + /* draw text */ + for (i=0; iwidth,ypos+i*fontsize,(GXColor)WHITE); + } + +#ifdef HW_RVL + if (Shutdown) + { + gxTextureClose(&window); + gxTextureClose(&top); + gxTextureClose(&w_pointer); + GUI_DeleteMenu(parent); + GUI_FadeOut(); + shutdown(); + SYS_ResetSystem(SYS_POWEROFF, 0, 0); + } + else if (m_input.ir.valid) + { + /* get cursor position */ + x = m_input.ir.x; + y = m_input.ir.y; + + /* draw wiimote pointer */ + gxDrawTextureRotate(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,m_input.ir.angle,255); + } +#endif + + /* update screen */ + gxSetScreen(); + + /* wait for exit buttons */ + if (m_input.keys) + quit = 1; + } + + /* reset initial vertical offset */ + + /* slide out */ + yoffset = 0; + while (yoffset < (ywindow + window->height)) + { + /* draw parent menu */ + GUI_DrawMenu(parent); + + /* draw window */ + gxDrawTexture(window,xwindow,ywindow-yoffset,window->width,window->height,230); + gxDrawTexture(top,xwindow,ywindow-yoffset,top->width,top->height,255); + + /* draw title */ + FONT_writeCenter(title,20,xwindow,xwindow+window->width,ywindow+(top->height-20)/2+20-yoffset,(GXColor)WHITE); + + /* draw text */ + for (i=0; iwidth,ypos+i*fontsize-yoffset,(GXColor)WHITE); + + /* update display */ + gxSetScreen(); + + /* slide speed */ + yoffset += 60; + } + + /* restore helper comment */ + if (parent->helpers[1]) + parent->helpers[1]->data = data; + + /* final position */ + GUI_DrawMenu(parent); + gxSetScreen(); + + /* close textures */ + gxTextureClose(&window); + gxTextureClose(&top); +} + +/* Option Window (returns selected item) */ +int GUI_OptionWindow(gui_menu *parent, char *title, char *items[], u8 nb_items) +{ + int i, ret, quit = 0; + int old, selected = 0; + s16 p; + butn_data button; + +#ifdef HW_RVL + int x,y; +#endif + + /* initialize buttons data */ + button.texture[0] = gxTextureOpenPNG(Button_text_png,0); + button.texture[1] = gxTextureOpenPNG(Button_text_over_png,0); + + /* initialize texture window */ + gx_texture *window = gxTextureOpenPNG(Frame_s1_png,0); + gx_texture *top = gxTextureOpenPNG(Frame_s1_title_png,0); + + /* get initial positions */ + int w = button.texture[0]->width; + int h = button.texture[0]->height; + int xwindow = (640 - window->width)/2; + int ywindow = (480 - window->height)/2; + int xpos = xwindow + (window->width - w)/2; + int ypos = (window->height - top->height - (h*nb_items) - (nb_items-1)*20)/2; + ypos = ypos + ywindow + top->height; + + /* disable helper comment */ + const u8 *data = NULL; + if (parent->helpers[1]) + { + data = parent->helpers[1]->data; + parent->helpers[1]->data = 0; + } + + /* slide in */ + int yoffset = ywindow + window->height; + while (yoffset > 0) + { + /* draw parent menu */ + GUI_DrawMenu(parent); + + /* draw window */ + gxDrawTexture(window,xwindow,ywindow-yoffset,window->width,window->height,230); + gxDrawTexture(top,xwindow,ywindow-yoffset,top->width,top->height,255); + + /* draw title */ + FONT_writeCenter(title,20,xwindow,xwindow+window->width,ywindow+(top->height-20)/2+20-yoffset,(GXColor)WHITE); + + /* draw buttons + text */ + for (i=0; iwidth,window->height,230); + gxDrawTexture(top,xwindow,ywindow,top->width,top->height,255); + + /* draw title */ + FONT_writeCenter(title,20,xwindow,xwindow+window->width,ywindow+(top->height-20)/2+20,(GXColor)WHITE); + + /* draw buttons + text */ + for (i=0; iwidth/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,m_input.ir.angle,255); + + /* check for valid buttons */ + selected = -1; + for (i=0; i=xpos)&&(x<=(xpos+w))&&(y>=ypos+i*(20 + h))&&(y<=(ypos+i*(20+h)+h))) + { + selected = i; + break; + } + } + } + else + { + /* reinitialize selection */ + if (selected == -1) + selected = 0; + } +#endif + + /* update screen */ + gxSetScreen(); + + /* update selection */ + if (p & PAD_BUTTON_UP) + { + if (selected > 0) + selected --; + } + else if (p & PAD_BUTTON_DOWN) + { + if (selected < (nb_items -1)) + selected ++; + } + + /* sound fx */ + if (selected != old) + { + if (selected >= 0) + { + ASND_SetVoice(ASND_GetFirstUnusedVoice(),VOICE_MONO_16BIT,22050,0,(u8 *)button_over_pcm,button_over_pcm_size, + ((int)config.sfx_volume * 255) / 100,((int)config.sfx_volume * 255) / 100,NULL); + } + } + + if (p & PAD_BUTTON_A) + { + if (selected >= 0) + { + quit = 1; + ret = selected; + } + } + else if (p & PAD_BUTTON_B) + { + quit = 1; + ret = -1; + } + } + + /* slide out */ + yoffset = 0; + while (yoffset < (ywindow + window->height)) + { + /* draw parent menu */ + GUI_DrawMenu(parent); + + /* draw window + header */ + gxDrawTexture(window,xwindow,ywindow-yoffset,window->width,window->height,230); + gxDrawTexture(top,xwindow,ywindow-yoffset,top->width,top->height,255); + + /* draw title */ + FONT_writeCenter(title,20,xwindow,xwindow+window->width,ywindow+(top->height-20)/2+20-yoffset,(GXColor)WHITE); + + /* draw buttons + text */ + for (i=0; ihelpers[1]) + parent->helpers[1]->data = data; + + /* final position */ + GUI_DrawMenu(parent); + gxSetScreen(); + + /* close textures */ + gxTextureClose(&window); + gxTextureClose(&top); + gxTextureClose(&button.texture[0]); + gxTextureClose(&button.texture[1]); + + return ret; +} + +/* Option Box */ +void GUI_OptionBox(gui_menu *parent, optioncallback cb, char *title, void *option, float step, float min, float max, u8 type) +{ + gx_texture *arrow[2]; + arrow[0] = gxTextureOpenPNG(Button_arrow_png,0); + arrow[1] = gxTextureOpenPNG(Button_arrow_over_png,0); + gx_texture *window = gxTextureOpenPNG(Frame_s2_png,0); + gx_texture *top = gxTextureOpenPNG(Frame_s2_title_png,0); + + /* window position */ + int xwindow = 166; + int ywindow = 160; + + /* arrows position */ + int xleft = 206; + int xright = 392; + int yleft = 238; + int yright = 238; + + /* disable action button helper */ + if (parent->helpers[1]) + parent->helpers[1]->data = 0; + + /* slide in */ + char msg[16]; + int yoffset = ywindow + window->height; + while (yoffset > 0) + { + /* draw parent menu */ + GUI_DrawMenu(parent); + + /* draw window */ + gxDrawTexture(window,xwindow,ywindow-yoffset,window->width,window->height,225); + gxDrawTexture(top,xwindow,ywindow-yoffset,top->width,top->height,255); + + /* display title */ + FONT_writeCenter(title,20,xwindow,xwindow+window->width,ywindow+(top->height-20)/2+20-yoffset,(GXColor)WHITE); + + /* update display */ + gxSetScreen(); + + /* slide speed */ + yoffset -= 60; + } + + /* display option box */ + int quit = 0; + int modified = 0; + int selected = -1; + s16 p; +#ifdef HW_RVL + int x,y; +#endif + + while (!quit) + { + /* draw parent menu */ + GUI_DrawMenu(parent); + + /* draw window */ + gxDrawTexture(window,xwindow,ywindow,window->width,window->height,225); + gxDrawTexture(top,xwindow,ywindow,top->width,top->height,255); + + /* display title */ + FONT_writeCenter(title,20,xwindow,xwindow+window->width,ywindow+(top->height-20)/2+20,(GXColor)WHITE); + + /* option type */ + if (type) + { + /* integer type */ + if (*(s16 *)option < 0) + sprintf(msg,"-%d",abs(*(s16 *)option)); + else + sprintf(msg,"%d",abs(*(s16 *)option)); + } + else + { + /* float type */ + if (*(float *)option < 0.0) + sprintf(msg,"-%1.2f",fabs(*(float *)option)); + else + sprintf(msg,"%1.2f",fabs(*(float *)option)); + } + + /* draw option text */ + FONT_writeCenter(msg,24,xwindow,xwindow+window->width,272,(GXColor)WHITE); + + /* update inputs */ + p = m_input.keys; + + /* draw buttons */ + if (selected < 0) + { + /* nothing selected */ + gxDrawTexture(arrow[0],xleft,yleft,arrow[0]->width,arrow[0]->height,255); + gxDrawTextureRotate(arrow[0],xright,yright,arrow[0]->width,arrow[0]->height,180.0,255); + } + +#ifdef HW_RVL + else if (selected) + { + /* right button selected */ + gxDrawTexture(arrow[0],xleft,yleft,arrow[0]->width,arrow[0]->height,255); + gxDrawTextureRotate(arrow[1],xright-4,yright-4,arrow[1]->width+8,arrow[1]->height+8,180.0,255); + } + else + { + /* left button selected */ + gxDrawTexture(arrow[1],xleft-4,yleft-4,arrow[1]->width+8,arrow[1]->height+8,255); + gxDrawTextureRotate(arrow[0],xright,yright,arrow[0]->width,arrow[0]->height,180.0,255); + } + + selected = -1; + if (Shutdown) + { + gxTextureClose(&arrow[0]); + gxTextureClose(&arrow[1]); + gxTextureClose(&window); + gxTextureClose(&top); + gxTextureClose(&w_pointer); + GUI_DeleteMenu(parent); + GUI_FadeOut(); + shutdown(); + SYS_ResetSystem(SYS_POWEROFF, 0, 0); + } + else if (m_input.ir.valid) + { + /* get cursor position */ + x = m_input.ir.x; + y = m_input.ir.y; + + /* draw wiimote pointer */ + gxDrawTextureRotate(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,m_input.ir.angle,255); + + /* check for valid buttons */ + if ((x>=xleft)&&(x<=(xleft+arrow[0]->width))&&(y>=yleft)&&(y<=(yleft+arrow[0]->height))) + { + selected = 0; + if (p & PAD_BUTTON_A) + p |= PAD_BUTTON_LEFT; + } + else if ((x>=xright)&&(x<=(xright+arrow[0]->width))&&(y>=yright)&&(y<=(yright+arrow[0]->height))) + { + selected = 1; + if (p & PAD_BUTTON_A) + p |= PAD_BUTTON_RIGHT; + } + } +#endif + + /* update screen */ + gxSetScreen(); + + /* check input */ + if (p&PAD_BUTTON_LEFT) + { + /* decrement option value */ + if (type) + { + /* integer type */ + *(s16 *)option -= (s16)step; + if (*(s16 *)option < (s16)min) + *(s16 *)option = (s16)max; + } + else + { + /* float type */ + *(float *)option -= step; + if (*(float *)option < min) + *(float *)option = max; + } + + modified = 1; + } + else if (p&PAD_BUTTON_RIGHT) + { + /* increment option value */ + if (type) + { + /* integer type */ + *(s16 *)option += (s16)step; + if (*(s16 *)option > (s16)max) + *(s16 *)option = (s16)min; + } + else + { + /* float type */ + *(float *)option += step; + if (*(float *)option > max) + *(float *)option = min; + } + + modified = 1; + } + else if (p & PAD_BUTTON_B) + { + quit = 1; + } + + if (modified) + { + modified = 0; + + /* play sound effect */ + ASND_SetVoice(ASND_GetFirstUnusedVoice(),VOICE_MONO_16BIT,22050,0,(u8 *)button_over_pcm,button_over_pcm_size, + ((int)config.sfx_volume * 255) / 100,((int)config.sfx_volume * 255) / 100,NULL); + + /* option callback */ + if (cb) + cb(); + } + } + + /* slide out */ + yoffset = 0; ; + while (yoffset < (ywindow + window->height)) + { + /* draw parent menu */ + GUI_DrawMenu(parent); + + /* draw window */ + gxDrawTexture(window,xwindow,ywindow-yoffset,window->width,window->height,225); + gxDrawTexture(top,xwindow,ywindow-yoffset,top->width,top->height,255); + + /* display title */ + FONT_writeCenter(title,20,xwindow,xwindow+window->width,ywindow+(top->height-20)/2+20-yoffset,(GXColor)WHITE); + + /* update display */ + gxSetScreen(); + + /* slide speed */ + yoffset += 60; + } + + /* restore action button helper */ + if (parent->helpers[1]) + parent->helpers[1]->data = Key_A_png; + + /* final position */ + GUI_DrawMenu(parent); + gxSetScreen(); + + /* close textures */ + gxTextureClose(&arrow[0]); + gxTextureClose(&arrow[1]); + gxTextureClose(&window); + gxTextureClose(&top); +} + +/* Option Box with two parameters */ +void GUI_OptionBox2(gui_menu *parent, char *text_1, char *text_2, s16 *option_1, s16 *option_2, s16 step, s16 min, s16 max) +{ + gx_texture *arrow[2]; + arrow[0] = gxTextureOpenPNG(Button_arrow_png,0); + arrow[1] = gxTextureOpenPNG(Button_arrow_over_png,0); + gx_texture *window = gxTextureOpenPNG(Frame_s2_png,0); + + /* window position */ + int xwindow = 166; + int ywindow = 160; + + /* arrows position */ + int arrow_pos[4][2] = + { + {144,218}, + {452,218}, + {298,138}, + {298,298} + }; + + /* disable action button helper */ + if (parent->helpers[1]) + parent->helpers[1]->data = 0; + + /* slide in */ + char msg[16]; + int yoffset = ywindow + window->height; + while (yoffset > 0) + { + /* draw parent menu */ + GUI_DrawMenu(parent); + + /* draw window */ + gxDrawTexture(window,xwindow,ywindow-yoffset,window->width,window->height,225); + + /* update display */ + gxSetScreen(); + + /* slide speed */ + yoffset -= 60; + } + + /* display option box */ + int quit = 0; + int modified = 0; + s16 p; +#ifdef HW_RVL + int selected = -1; + int i,x,y; +#endif + + while (!quit) + { + /* draw parent menu */ + GUI_DrawMenu(parent); + + /* draw window */ + gxDrawTexture(window,xwindow,ywindow,window->width,window->height,225); + + /* draw options text */ + if (*option_1 < 0) + sprintf(msg,"%s: -%02d",text_1,abs(*option_1)); + else + sprintf(msg,"%s: +%02d",text_1,abs(*option_1)); + FONT_writeCenter(msg,24,xwindow,xwindow+window->width,240,(GXColor)WHITE); + if (*option_2 < 0) + sprintf(msg,"%s: -%02d",text_2,abs(*option_2)); + else + sprintf(msg,"%s: +%02d",text_2,abs(*option_2)); + FONT_writeCenter(msg,24,xwindow,xwindow+window->width,264,(GXColor)WHITE); + + /* update inputs */ + p = m_input.keys; + + /* draw buttons */ +#ifdef HW_RVL + switch (selected) + { + case 0: /* left button */ + gxDrawTexture(arrow[1],arrow_pos[0][0]-4,arrow_pos[0][1]-4,arrow[0]->width+8,arrow[0]->height+8,255); + gxDrawTextureRotate(arrow[0],arrow_pos[1][0],arrow_pos[1][1],arrow[0]->width,arrow[0]->height,180.0,255); + gxDrawTextureRotate(arrow[0],arrow_pos[2][0],arrow_pos[2][1],arrow[0]->width,arrow[0]->height,90.0,255); + gxDrawTextureRotate(arrow[0],arrow_pos[3][0],arrow_pos[3][1],arrow[0]->width,arrow[0]->height,270.0,255); + if (p & PAD_BUTTON_A) p |= PAD_BUTTON_LEFT; + break; + + case 1: /* right button */ + gxDrawTexture(arrow[0],arrow_pos[0][0],arrow_pos[0][1],arrow[0]->width,arrow[0]->height,255); + gxDrawTextureRotate(arrow[1],arrow_pos[1][0]-4,arrow_pos[1][1]-4,arrow[0]->width+8,arrow[0]->height+8,180.0,255); + gxDrawTextureRotate(arrow[0],arrow_pos[2][0],arrow_pos[2][1],arrow[0]->width,arrow[0]->height,90.0,255); + gxDrawTextureRotate(arrow[0],arrow_pos[3][0],arrow_pos[3][1],arrow[0]->width,arrow[0]->height,270.0,255); + if (p & PAD_BUTTON_A) p |= PAD_BUTTON_RIGHT; + break; + + case 2: /* up button */ + gxDrawTexture(arrow[0],arrow_pos[0][0],arrow_pos[0][1],arrow[0]->width,arrow[0]->height,255); + gxDrawTextureRotate(arrow[0],arrow_pos[1][0],arrow_pos[1][1],arrow[0]->width,arrow[0]->height,180.0,255); + gxDrawTextureRotate(arrow[1],arrow_pos[2][0]-4,arrow_pos[2][1]-4,arrow[0]->width+8,arrow[0]->height+8,90.0,255); + gxDrawTextureRotate(arrow[0],arrow_pos[3][0],arrow_pos[3][1],arrow[0]->width,arrow[0]->height,270.0,255); + if (p & PAD_BUTTON_A) p |= PAD_BUTTON_UP; + break; + + case 3: /* down button */ + gxDrawTexture(arrow[0],arrow_pos[0][0],arrow_pos[0][1],arrow[0]->width,arrow[0]->height,255); + gxDrawTextureRotate(arrow[0],arrow_pos[1][0],arrow_pos[1][1],arrow[0]->width,arrow[0]->height,180.0,255); + gxDrawTextureRotate(arrow[0],arrow_pos[2][0],arrow_pos[2][1],arrow[0]->width,arrow[0]->height,90.0,255); + gxDrawTextureRotate(arrow[1],arrow_pos[3][0]-4,arrow_pos[3][1]-4,arrow[0]->width+8,arrow[0]->height+8,270.0,255); + if (p & PAD_BUTTON_A) p |= PAD_BUTTON_DOWN; + break; + + default: /* nothing selected */ + gxDrawTexture(arrow[0],arrow_pos[0][0],arrow_pos[0][1],arrow[0]->width,arrow[0]->height,255); + gxDrawTextureRotate(arrow[0],arrow_pos[1][0],arrow_pos[1][1],arrow[0]->width,arrow[0]->height,180.0,255); + gxDrawTextureRotate(arrow[0],arrow_pos[2][0],arrow_pos[2][1],arrow[0]->width,arrow[0]->height,90.0,255); + gxDrawTextureRotate(arrow[0],arrow_pos[3][0],arrow_pos[3][1],arrow[0]->width,arrow[0]->height,270.0,255); + break; + } + + if (Shutdown) + { + gxTextureClose(&arrow[0]); + gxTextureClose(&arrow[1]); + gxTextureClose(&window); + gxTextureClose(&w_pointer); + GUI_DeleteMenu(parent); + GUI_FadeOut(); + shutdown(); + SYS_ResetSystem(SYS_POWEROFF, 0, 0); + } + + /* update selection */ + selected = -1; + if (m_input.ir.valid) + { + /* get cursor position */ + x = m_input.ir.x; + y = m_input.ir.y; + + /* draw wiimote pointer */ + gxDrawTextureRotate(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,m_input.ir.angle,255); + + /* check for valid buttons */ + for (i=0; i<4; i++) + { + if ((x>=arrow_pos[i][0])&&(x<=(arrow_pos[i][0]+arrow[0]->width))&&(y>=arrow_pos[i][1])&&(y<=(arrow_pos[i][1]+arrow[0]->height))) + selected = i; + } + } +#else + gxDrawTexture(arrow[0],arrow_pos[0][0],arrow_pos[0][1],arrow[0]->width,arrow[0]->height,255); + gxDrawTextureRotate(arrow[0],arrow_pos[1][0],arrow_pos[1][1],arrow[0]->width,arrow[0]->height,180.0,255); + gxDrawTextureRotate(arrow[0],arrow_pos[2][0],arrow_pos[2][1],arrow[0]->width,arrow[0]->height,90.0,255); + gxDrawTextureRotate(arrow[0],arrow_pos[3][0],arrow_pos[3][1],arrow[0]->width,arrow[0]->height,270.0,255); +#endif + + /* update screen */ + gxSetScreen(); + + if (p&PAD_BUTTON_LEFT) + { + /* decrement option 1 value */ + *option_1 -= step; + if (*option_1 < min) + *option_1 = max; + modified = 1; + } + else if (p&PAD_BUTTON_RIGHT) + { + /* decrement option 1 value */ + *option_1 += step; + if (*option_1 > max) + *option_1 = min; + modified = 1; + } + else if (p&PAD_BUTTON_UP) + { + /* decrement option 2 value */ + *option_2 -= step; + if (*option_2 < min) + *option_2 = max; + modified = 1; + } + else if (p&PAD_BUTTON_DOWN) + { + /* increment option 2 value */ + *option_2 += step; + if (*option_2 > max) + *option_2 = min; + modified = 1; + } + else if (p & PAD_BUTTON_B) + { + quit = 1; + } + + if (modified) + { + modified = 0; + /* play sound effect */ + ASND_SetVoice(ASND_GetFirstUnusedVoice(),VOICE_MONO_16BIT,22050,0,(u8 *)button_over_pcm,button_over_pcm_size, + ((int)config.sfx_volume * 255) / 100,((int)config.sfx_volume * 255) / 100,NULL); + } + } + + /* slide out */ + yoffset = 0; ; + while (yoffset < (ywindow + window->height)) + { + /* draw parent menu */ + GUI_DrawMenu(parent); + + /* draw window */ + gxDrawTexture(window,xwindow,ywindow-yoffset,window->width,window->height,225); + + /* update display */ + gxSetScreen(); + + /* slide speed */ + yoffset += 60; + } + + /* restore action button helper */ + if (parent->helpers[1]) + parent->helpers[1]->data = Key_A_png; + + /* final position */ + GUI_DrawMenu(parent); + gxSetScreen(); + + /* close textures */ + gxTextureClose(&arrow[0]); + gxTextureClose(&arrow[1]); + gxTextureClose(&window); +} + +/* Interactive Message Box */ +/* Message Box displays a message until a specific action is completed */ + +/* Message Box LWP Thread */ +static void *MsgBox_Thread(gui_message *message_box) +{ + while (message_box->refresh) + { + /* draw parent menu */ + if (message_box->parent) + { + GUI_DrawMenu(message_box->parent); + } + else + { + gxClearScreen(bg_color); + } + + /* draw window */ + gxDrawTexture(message_box->window,166,160,message_box->window->width,message_box->window->height,230); + gxDrawTexture(message_box->top,166,160,message_box->top->width,message_box->top->height,255); + + /* draw title */ + if (message_box->title) + FONT_writeCenter(message_box->title,20,166,166+message_box->window->width,160+(message_box->top->height-20)/2+20,(GXColor)WHITE); + + /* draw box message */ + if (message_box->msg) + FONT_writeCenter(message_box->msg,18,166,166+message_box->window->width,248,(GXColor)WHITE); + + /* draw throbber */ + if (message_box->throbber) + gxDrawTextureRotate(message_box->throbber,166+(message_box->window->width-message_box->throbber->width)/2,160+message_box->window->height-message_box->throbber->height-20,message_box->throbber->width,message_box->throbber->height,(message_box->progress * 360.0) / 100.0, 255); + + /* draw exit message */ + if (message_box->buttonA) + { + FONT_writeCenter("Press to continue.",18,166,166+message_box->window->width,248+22,(GXColor)WHITE); + gxDrawTexture(message_box->buttonA, 166+116, 248+4+(18-message_box->buttonA->height)/2,message_box->buttonA->width, message_box->buttonA->height,255); + } + + /* update display */ + gxSetScreen(); + + /* update progression */ + message_box->progress++; + if (message_box->progress > 100) + message_box->progress = 0; + usleep(10); + } + + return 0; +} + +/* update current Message Box */ +void GUI_MsgBoxUpdate(char *title, char *msg) +{ + if (title) + strncpy(message_box.title,title,64); + if (msg) + strncpy(message_box.msg,msg,64); +} + +/* setup current Message Box */ +void GUI_MsgBoxOpen(char *title, char *msg, bool throbber) +{ + if (SILENT) + return; + + /* update text */ + GUI_MsgBoxUpdate(title,msg); + + /* ensure we are not already running */ + if (!message_box.refresh) + { + /* initialize default textures */ + message_box.window = gxTextureOpenPNG(Frame_s2_png,0); + message_box.top = gxTextureOpenPNG(Frame_s2_title_png,0); + if (throbber) + message_box.throbber = gxTextureOpenPNG(Frame_throbber_png,0); + + /* window position */ + int xwindow = 166; + int ywindow = 160; + int ypos = 248; + + /* disable helper comments */ + if (message_box.parent) + { + if (message_box.parent->helpers[0]) + message_box.parent->helpers[0]->data = 0; + if (message_box.parent->helpers[1]) + message_box.parent->helpers[1]->data = 0; + } + + /* slide in */ + int yoffset = ywindow + message_box.window->height; + while (yoffset > 0) + { + /* draw parent menu */ + if (message_box.parent) + { + GUI_DrawMenu(message_box.parent); + } + else + { + gxClearScreen(bg_color); + } + + /* draw window */ + gxDrawTexture(message_box.window,xwindow,ywindow-yoffset,message_box.window->width,message_box.window->height,230); + gxDrawTexture(message_box.top,xwindow,ywindow-yoffset,message_box.top->width,message_box.top->height,255); + + /* draw title */ + if (title) + FONT_writeCenter(title,20,xwindow,xwindow+message_box.window->width,ywindow+(message_box.top->height-20)/2+20-yoffset,(GXColor)WHITE); + + /* draw box message */ + if (msg) + FONT_writeCenter(msg,18,xwindow,xwindow+message_box.window->width,ypos-yoffset,(GXColor)WHITE); + + /* update display */ + gxSetScreen(); + + /* slide speed */ + yoffset -= 60; + } + + /* create LWP thread for MessageBox refresh */ + message_box.refresh = TRUE; + LWP_CreateThread (&msgboxthread, (void *)MsgBox_Thread, &message_box, NULL, 0, 70); + } +} + +/* Close current messagebox */ +void GUI_MsgBoxClose(void) +{ + if (message_box.refresh) + { + /* suspend MessageBox refresh */ + message_box.refresh = FALSE; + LWP_JoinThread(msgboxthread, NULL); + + /* window position */ + int xwindow = 166; + int ywindow = 160; + int ypos = 248; + + /* slide out */ + int yoffset = 0; + while (yoffset < (ywindow + message_box.window->height)) + { + /* draw parent menu */ + if (message_box.parent) + { + GUI_DrawMenu(message_box.parent); + } + else + { + gxClearScreen(bg_color); + } + + /* draw window */ + gxDrawTexture(message_box.window,xwindow,ywindow-yoffset,message_box.window->width,message_box.window->height,230); + gxDrawTexture(message_box.top,xwindow,ywindow-yoffset,message_box.top->width,message_box.top->height,255); + + /* draw title */ + if (message_box.title) + FONT_writeCenter(message_box.title,20,xwindow,xwindow+message_box.window->width,ywindow+(message_box.top->height-20)/2+20-yoffset,(GXColor)WHITE); + + /* draw text */ + if (message_box.msg) + FONT_writeCenter(message_box.msg,18,xwindow,xwindow+message_box.window->width,ypos-yoffset,(GXColor)WHITE); + + /* update display */ + gxSetScreen(); + + /* slide speed */ + yoffset += 60; + } + + if (message_box.parent) + { + /* restore helper comment */ + if (message_box.parent->helpers[0]) + message_box.parent->helpers[0]->data = Key_B_png; + if (message_box.parent->helpers[1]) + message_box.parent->helpers[1]->data = Key_A_png; + + /* final position */ + GUI_DrawMenu(message_box.parent); + } + else + { + gxClearScreen(bg_color); + } + + gxSetScreen(); + + /* clear all textures */ + gxTextureClose(&message_box.window); + gxTextureClose(&message_box.top); + gxTextureClose(&message_box.buttonA); + gxTextureClose(&message_box.throbber); + } +} + +void GUI_WaitPrompt(char *title, char *msg) +{ + if (SILENT) + return; + + /* clear unused texture */ + gxTextureClose(&message_box.throbber); + + /* open or update message box */ + GUI_MsgBoxOpen(title, msg, 0); + + /* allocate texture */ + message_box.buttonA = gxTextureOpenPNG(Key_A_png,0); + + /* wait for button A */ + while (m_input.keys & PAD_BUTTON_A) + VIDEO_WaitVSync(); + while (!(m_input.keys & PAD_BUTTON_A)) + VIDEO_WaitVSync(); + + /* always close message box */ + GUI_MsgBoxClose(); +} + +/* Basic Fading */ +void GUI_FadeOut() +{ + int alpha = 0; + while (alpha < 256) + { + gxDrawRectangle(0, 0, 640, 480, alpha, (GXColor)BLACK); + gxSetScreen(); + alpha +=3; + } +} diff --git a/genplus-gx/gx/gui/gui.h b/genplus-gx/gx/gui/gui.h new file mode 100644 index 0000000000..3f53a471be --- /dev/null +++ b/genplus-gx/gx/gui/gui.h @@ -0,0 +1,245 @@ +/**************************************************************************** + * gui.c + * + * generic GUI Engine (using GX rendering) + * + * Copyright Eke-Eke (2009-2010) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _GUI_H +#define _GUI_H + +#define BG_COLOR_MAX 15 + +/*****************************************************************************/ +/* GUI Buttons state */ +/*****************************************************************************/ +#define BUTTON_VISIBLE 0x01 +#define BUTTON_ACTIVE 0x02 +#define BUTTON_SELECTED 0x04 +#define BUTTON_OVER_SFX 0x08 +#define BUTTON_SELECT_SFX 0x10 +#define BUTTON_FADE 0x20 +#define BUTTON_SLIDE_LEFT 0x40 +#define BUTTON_SLIDE_RIGHT 0x80 +#define BUTTON_SLIDE_TOP 0x100 +#define BUTTON_SLIDE_BOTTOM 0x200 + +/*****************************************************************************/ +/* GUI Image state */ +/*****************************************************************************/ +#define IMAGE_VISIBLE 0x01 +#define IMAGE_REPEAT 0x02 +#define IMAGE_FADE 0x04 +#define IMAGE_SLIDE_LEFT 0x08 +#define IMAGE_SLIDE_RIGHT 0x10 +#define IMAGE_SLIDE_TOP 0x20 +#define IMAGE_SLIDE_BOTTOM 0x40 + +/*****************************************************************************/ +/* Generic GUI structures */ +/*****************************************************************************/ + +/* Item descriptor*/ +typedef struct +{ + gx_texture *texture; /* temporary texture data */ + const u8 *data; /* pointer to png image data (items icon only) */ + char text[64]; /* item string (items list only) */ + char comment[64]; /* item comment */ + u16 x; /* item image or text X position (upper left corner) */ + u16 y; /* item image or text Y position (upper left corner) */ + u16 w; /* item image or text width */ + u16 h; /* item image or text height */ +} gui_item; + +/* Button Data descriptor */ +typedef struct +{ + gx_texture *texture[2]; /* temporary texture datas */ + const u8 *image[2]; /* pointer to png image datas (default) */ +} butn_data; + +/* Button descriptor */ +typedef struct +{ + butn_data *data; /* pointer to button image/texture data */ + u16 state; /* button state (ACTIVE,VISIBLE,SELECTED...) */ + u8 shift[4]; /* direction offsets */ + u16 x; /* button image X position (upper left corner) */ + u16 y; /* button image Y position (upper left corner) */ + u16 w; /* button image pixels width */ + u16 h; /* button image pixels height */ +} gui_butn; + +/* Image descriptor */ +typedef struct +{ + gx_texture *texture; /* temporary texture data */ + const u8 *data; /* pointer to png image data */ + u8 state; /* image state (VISIBLE) */ + u16 x; /* image X position (upper left corner) */ + u16 y; /* image Y position (upper left corner) */ + u16 w; /* image width */ + u16 h; /* image height */ + u8 alpha; /* alpha transparency */ +} gui_image; + +/* Menu descriptor */ +typedef struct +{ + char title[64]; /* menu title */ + s8 selected; /* index of selected item */ + s8 offset; /* items list offset */ + u8 max_items; /* total number of items */ + u8 max_buttons; /* total number of buttons */ + u8 max_images; /* total number of background images */ + u8 screenshot; /* game screen background */ + gui_item *items; /* menu items */ + gui_butn *buttons; /* menu buttons */ + gui_image *bg_images; /* background images */ + gui_item *helpers[2]; /* left & right key comments */ + gui_butn *arrows[2]; /* arrows buttons */ + void (*cb)(void); /* specific draw callback */ +} gui_menu; + +typedef struct +{ + u32 progress; /* progress counter */ + bool refresh; /* messagebox current state */ + gui_menu *parent; /* parent menu */ + char title[64]; /* box title */ + char msg[64]; /* box message */ + gx_texture *window; /* pointer to box texture */ + gx_texture *top; /* pointer to box title texture */ + gx_texture *buttonA; /* pointer to button A texture */ + gx_texture *throbber; /* pointer to throbber texture */ +} gui_message; + +/* Menu inputs */ +struct t_input_menu +{ + u16 keys; +#ifdef HW_RVL + struct ir_t ir; +#endif +} m_input; + +/* Optionbox callback */ +typedef void (*optioncallback)(void); + +/* Generic textures*/ +#ifdef HW_RVL +extern gx_texture *w_pointer; +#endif + +/* Generic backgrounds */ +extern const u8 Bg_layer_png[]; +extern const u8 Bg_overlay_png[]; +extern const u8 Banner_main_png[]; +extern const u8 Banner_bottom_png[]; +extern const u8 Banner_top_png[]; +extern const u8 Main_logo_png[]; + +/* Generic frames */ +extern const u8 Frame_s1_png[]; +extern const u8 Frame_s2_png[]; +extern const u8 Frame_s3_png[]; +extern const u8 Frame_s1_title_png[]; +extern const u8 Frame_s2_title_png[]; +extern const u8 Frame_throbber_png[]; + +/* Generic Buttons */ +extern const u8 Button_text_png[]; +extern const u8 Button_text_over_png[]; +extern const u8 Button_icon_png[]; +extern const u8 Button_icon_over_png[]; +extern const u8 Button_icon_sm_png[]; +extern const u8 Button_icon_sm_over_png[]; +extern const u8 Button_up_png[]; +extern const u8 Button_up_over_png[]; +extern const u8 Button_down_png[]; +extern const u8 Button_down_over_png[]; +extern const u8 Button_arrow_png[]; +extern const u8 Button_arrow_over_png[]; +extern const u8 Button_digit_png[]; +extern const u8 Button_digit_over_png[]; + +/* Generic images*/ +#ifdef HW_RVL +#define Key_A_png Key_A_wii_png +#define Key_B_png Key_B_wii_png +extern const u8 generic_point_png[]; +extern const u8 Key_A_wii_png[]; +extern const u8 Key_B_wii_png[]; +#else +#define Key_A_png Key_A_gcn_png +#define Key_B_png Key_B_gcn_png +extern const u8 Key_A_gcn_png[]; +extern const u8 Key_B_gcn_png[]; +#endif +extern const u8 Star_full_png[]; +extern const u8 Star_empty_png[]; +extern const u8 Overlay_bar_png[]; + +/* Generic Sounds */ +extern const u8 button_over_pcm[]; +extern const u8 button_select_pcm[]; +extern const u8 intro_pcm[]; +extern const u32 button_select_pcm_size; +extern const u32 button_over_pcm_size; +extern const u32 intro_pcm_size; + +extern u8 SILENT; + +extern void GUI_InitMenu(gui_menu *menu); +extern void GUI_DeleteMenu(gui_menu *menu); +extern void GUI_DrawMenu(gui_menu *menu); +extern void GUI_DrawMenuFX(gui_menu *menu, u8 speed, u8 out); +extern void GUI_SlideMenuTitle(gui_menu *m, int title_offset); +extern int GUI_UpdateMenu(gui_menu *menu); +extern int GUI_RunMenu(gui_menu *menu); +extern void GUI_TextWindow(gui_menu *parent, char *title, char items[][64], u8 nb_items, u8 fontsize); +extern int GUI_OptionWindow(gui_menu *parent, char *title, char *items[], u8 nb_items); +extern void GUI_OptionBox(gui_menu *parent, optioncallback cb, char *title, void *option, float step, float min, float max, u8 type); +extern void GUI_OptionBox2(gui_menu *parent, char *text_1, char *text_2, s16 *option_1, s16 *option_2, s16 step, s16 min, s16 max); +extern void GUI_MsgBoxOpen(char *title, char *msg, bool throbber); +extern void GUI_MsgBoxUpdate(char *title, char *msg); +extern void GUI_MsgBoxClose(void); +extern void GUI_WaitPrompt(char *title, char *msg); +extern void GUI_FadeOut(); +extern GXColor *GUI_GetBgColor(void); +extern void GUI_SetBgColor(u8 color); + +#endif diff --git a/genplus-gx/gx/gui/legal.c b/genplus-gx/gx/gui/legal.c new file mode 100644 index 0000000000..c3d49da8c6 --- /dev/null +++ b/genplus-gx/gx/gui/legal.c @@ -0,0 +1,172 @@ +/**************************************************************************** + * legal.c + * + * Genesis Plus GX Disclaimer + * + * Copyright Eke-Eke (2009-2012) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "font.h" +#include "gui.h" + +extern const u8 Bg_intro_c1_png[]; +extern const u8 Bg_intro_c2_png[]; +extern const u8 Bg_intro_c3_png[]; +extern const u8 Bg_intro_c4_png[]; + +/* + * This is the legal stuff - which must be shown at program startup + * Any derivative work MUST include the same textual output. + * + */ + +static void show_disclaimer(int ypos) +{ + FONT_writeCenter ("DISCLAIMER",22,0,640,ypos,(GXColor)WHITE); + ypos += 32; + FONT_writeCenter ("This is a free software, and you are welcome",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("to redistribute it under the conditions of the",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("license that you should have received with this",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("program. You may not sell, lease, rent or generally",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("use this software in any commercial product or activity.",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("Authors can not be held responsible for any damage or",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("or dysfunction that could occur while using this port.",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("You may not distribute this software with any ROM image",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("unless you have the legal right to distribute them.",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("This software is not endorsed by or affiliated",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("with Sega Enterprises Ltd or Nintendo Co Ltd.",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("All trademarks and registered trademarks are",20,0,640,ypos,(GXColor)WHITE); + ypos += 20; + FONT_writeCenter ("the property of their respective owners.",20,0,640,ypos,(GXColor)WHITE); + ypos += 38; +} + +void legal () +{ + int count = 2000; + int vis = 0; + +#ifdef HW_RVL + gx_texture *button = gxTextureOpenPNG(Key_A_wii_png,0); +#else + gx_texture *button = gxTextureOpenPNG(Key_A_gcn_png,0); +#endif + gx_texture *logo = gxTextureOpenPNG(Bg_intro_c4_png,0); + + gxClearScreen((GXColor)BLACK); + show_disclaimer(56); + gxDrawTexture(logo, (640-logo->width)/2, 480-24-logo->height, logo->width, logo->height,255); + gxSetScreen(); + sleep(1); + + while (!m_input.keys && count) + { + gxClearScreen((GXColor)BLACK); + show_disclaimer(56); + if (count%25 == 0) vis^=1; + if (vis) + { + FONT_writeCenter("Press button to continue.",24,0,640,366,(GXColor)SKY_BLUE); + gxDrawTexture(button, 220, 366-24+(24-button->height)/2, button->width, button->height,255); + } + gxDrawTexture(logo, (640-logo->width)/2, 480-24-logo->height, logo->width, logo->height,255); + gxSetScreen(); + count--; + } + + gxTextureClose(&button); + gxTextureClose(&logo); + + if (count > 0) + { + ASND_Pause(0); + int voice = ASND_GetFirstUnusedVoice(); + ASND_SetVoice(voice,VOICE_MONO_16BIT,44100,0,(u8 *)button_select_pcm,button_select_pcm_size,200,200,NULL); + GUI_FadeOut(); + ASND_Pause(1); + return; + } + + gxClearScreen((GXColor)BLACK); + gx_texture *texture = gxTextureOpenPNG(Bg_intro_c1_png,0); + if (texture) + { + gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255); + if (texture->data) free(texture->data); + free(texture); + } + gxSetScreen(); + + sleep (1); + + gxClearScreen((GXColor)WHITE); + texture = gxTextureOpenPNG(Bg_intro_c2_png,0); + if (texture) + { + gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255); + if (texture->data) free(texture->data); + free(texture); + } + gxSetScreen(); + + sleep (1); + + gxClearScreen((GXColor)BLACK); + texture = gxTextureOpenPNG(Bg_intro_c3_png,0); + if (texture) + { + gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255); + if (texture->data) free(texture->data); + free(texture); + } + gxSetScreen(); + + ASND_Pause(0); + int voice = ASND_GetFirstUnusedVoice(); + ASND_SetVoice(voice,VOICE_MONO_16BIT,44100,0,(u8 *)intro_pcm,intro_pcm_size,200,200,NULL); + sleep (2); + ASND_Pause(1); +} diff --git a/genplus-gx/gx/gui/menu.c b/genplus-gx/gx/gui/menu.c new file mode 100644 index 0000000000..1ca3651e32 --- /dev/null +++ b/genplus-gx/gx/gui/menu.c @@ -0,0 +1,3683 @@ +/**************************************************************************** + * menu.c + * + * Genesis Plus GX menu + * + * Copyright Eke-Eke (2009-2013) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "font.h" +#include "gui.h" +#include "filesel.h" +#include "cheats.h" +#include "file_load.h" +#include "file_slot.h" + +#ifdef HW_RVL +#include +#endif + +#include +#include + +/* Credits */ +extern const u8 Bg_credits_png[]; + +/* Main menu */ +extern const u8 Main_load_png[]; +extern const u8 Main_options_png[]; +extern const u8 Main_quit_png[]; +extern const u8 Main_file_png[]; +extern const u8 Main_reset_png[]; +extern const u8 Main_cheats_png[]; +extern const u8 Main_showinfo_png[]; +extern const u8 Main_takeshot_png[]; +#ifdef HW_RVL +extern const u8 Main_play_wii_png[]; +#else +extern const u8 Main_play_gcn_png[]; +#endif + +/* Options menu */ +extern const u8 Option_menu_png[]; +extern const u8 Option_ctrl_png[]; +extern const u8 Option_sound_png[]; +extern const u8 Option_video_png[]; +extern const u8 Option_system_png[]; + +/* Load ROM menu */ +extern const u8 Load_recent_png[]; +extern const u8 Load_md_png[]; +extern const u8 Load_ms_png[]; +extern const u8 Load_gg_png[]; +extern const u8 Load_sg_png[]; +extern const u8 Load_cd_png[]; + +/* Save Manager menu */ +extern const u8 Button_load_png[]; +extern const u8 Button_load_over_png[]; +extern const u8 Button_save_png[]; +extern const u8 Button_save_over_png[]; +extern const u8 Button_special_png[]; +extern const u8 Button_special_over_png[]; +extern const u8 Button_delete_png[]; +extern const u8 Button_delete_over_png[]; + +/* Controller Settings */ +extern const u8 Ctrl_4wayplay_png[]; +extern const u8 Ctrl_gamepad_md_png[]; +extern const u8 Ctrl_gamepad_ms_png[]; +extern const u8 Ctrl_justifiers_png[]; +extern const u8 Ctrl_menacer_png[]; +extern const u8 Ctrl_mouse_png[]; +extern const u8 Ctrl_xe_a1p_png[]; +extern const u8 Ctrl_activator_png[]; +extern const u8 Ctrl_lightphaser_png[]; +extern const u8 Ctrl_paddle_png[]; +extern const u8 Ctrl_sportspad_png[]; +extern const u8 Ctrl_none_png[]; +extern const u8 Ctrl_teamplayer_png[]; +extern const u8 Ctrl_pad3b_png[]; +extern const u8 Ctrl_pad6b_png[]; +extern const u8 Ctrl_config_png[]; +extern const u8 ctrl_option_off_png[]; +extern const u8 ctrl_option_on_png[]; +extern const u8 ctrl_gamecube_png[]; +#ifdef HW_RVL +extern const u8 ctrl_classic_png[]; +extern const u8 ctrl_nunchuk_png[]; +extern const u8 ctrl_wiimote_png[]; +#endif + +/* Generic images */ +extern const u8 Button_sm_blue_png[]; +extern const u8 Button_sm_grey_png[]; +extern const u8 Button_sm_yellow_png[]; + +/* Exit callback */ +void (*reload)(void); + + +/*****************************************************************************/ +/* Specific Menu Callbacks */ +/*****************************************************************************/ +static void ctrlmenu_cb(void); +static void savemenu_cb(void); +static void mainmenu_cb(void); + +/*****************************************************************************/ +/* Generic Buttons data */ +/*****************************************************************************/ +static butn_data arrow_up_data = +{ + {NULL,NULL}, + {Button_up_png,Button_up_over_png} +}; + +static butn_data arrow_down_data = +{ + {NULL,NULL}, + {Button_down_png,Button_down_over_png} +}; + +static butn_data button_text_data = +{ + {NULL,NULL}, + {Button_text_png,Button_text_over_png} +}; + +static butn_data button_icon_data = +{ + {NULL,NULL}, + {Button_icon_png,Button_icon_over_png} +}; + +static butn_data button_icon_sm_data = +{ + {NULL,NULL}, + {Button_icon_sm_png,Button_icon_sm_over_png} +}; + +static butn_data button_player_data = +{ + {NULL,NULL}, + {Button_sm_blue_png,Button_sm_yellow_png} +}; + +static butn_data button_player_none_data = +{ + {NULL,NULL}, + {Button_sm_grey_png,NULL} +}; + +static butn_data button_load_data = +{ + {NULL,NULL}, + {Button_load_png,Button_load_over_png} +}; + +static butn_data button_save_data = +{ + {NULL,NULL}, + {Button_save_png,Button_save_over_png} +}; + +static butn_data button_special_data = +{ + {NULL,NULL}, + {Button_special_png,Button_special_over_png} +}; + +static butn_data button_delete_data = +{ + {NULL,NULL}, + {Button_delete_png,Button_delete_over_png} +}; + +/*****************************************************************************/ +/* Generic GUI items */ +/*****************************************************************************/ +static gui_item action_cancel = +{ + NULL,Key_B_png,"","Back",10,422,28,28 +}; + +static gui_item action_select = +{ + NULL,Key_A_png,"","",602,422,28,28 +}; + +/*****************************************************************************/ +/* GUI backgrounds images */ +/*****************************************************************************/ +static gui_image bg_main[4] = +{ + {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Banner_main_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,0,340,640,140,255}, + {NULL,Main_logo_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,202,362,232,56,255} +}; + +static gui_image bg_misc[5] = +{ + {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Banner_top_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,0,0,640,108,255}, + {NULL,Banner_bottom_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,0,380,640,100,255}, + {NULL,Main_logo_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,466,40,152,44,255} +}; + +static gui_image bg_ctrls[8] = +{ + {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255}, + {NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255}, + {NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255}, + {NULL,Frame_s2_png,IMAGE_VISIBLE,38,72,316,168,128}, + {NULL,Frame_s2_png,IMAGE_VISIBLE,38,242,316,168,128}, + {NULL,Frame_s3_png,IMAGE_SLIDE_RIGHT,400,134,292,248,128} +}; + +static gui_image bg_list[6] = +{ + {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255}, + {NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255}, + {NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255}, + {NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,76} +}; + +static gui_image bg_saves[8] = +{ + {NULL,NULL,0,0,0,0,0,255}, + {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255}, + {NULL,Banner_top_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,0,0,640,108,255}, + {NULL,Banner_bottom_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,0,380,640,100,255}, + {NULL,Main_logo_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,466,40,152,44,255}, + {NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,76}, + {NULL,Frame_s1_png,IMAGE_SLIDE_RIGHT,468,108,372,296,76} +}; + +/*****************************************************************************/ +/* Menu Items description */ +/*****************************************************************************/ + +/* Main menu */ +static gui_item items_main[10] = +{ + {NULL,Main_load_png ,"","",114,162,80,92}, + {NULL,Main_options_png ,"","",290,166,60,88}, + {NULL,Main_quit_png ,"","",460,170,52,84}, + {NULL,Main_file_png ,"","",114,216,80,92}, + {NULL,Main_reset_png ,"","",294,227,52,80}, + {NULL,Main_cheats_png ,"","",454,218,64,92}, + {NULL,NULL ,"","", 10,334,84,32}, +#ifdef HW_RVL + {NULL,Main_play_wii_png,"","", 10,372,84,32}, +#else + {NULL,Main_play_gcn_png,"","", 10,372,84,32}, +#endif + {NULL,Main_takeshot_png,"","",546,334,84,32}, + {NULL,Main_showinfo_png,"","",546,372,84,32} +}; + +/* Controllers menu */ +static gui_item items_ctrls[13] = +{ + {NULL,NULL,"","", 0, 0, 0, 0}, + {NULL,NULL,"","", 0, 0, 0, 0}, + {NULL,NULL,"","",305, 0, 24, 0}, + {NULL,NULL,"","",305, 0, 24, 0}, + {NULL,NULL,"","",305, 0, 24, 0}, + {NULL,NULL,"","",305, 0, 24, 0}, + {NULL,NULL,"","",305, 0, 24, 0}, + {NULL,NULL,"","",305, 0, 24, 0}, + {NULL,NULL,"","",305, 0, 24, 0}, + {NULL,NULL,"","",305, 0, 24, 0}, + {NULL,NULL,"","", 0, 0, 0, 0}, + {NULL,NULL,"","", 0, 0, 0, 0}, + {NULL,Ctrl_config_png,"Keys\nConfig","Configure Controller Keys",530,306,32,32} +}; + +/* Load menu */ +static gui_item items_load[6] = +{ + {NULL,Load_recent_png,"","Load recently played games", 119,144,72, 92}, + {NULL,Load_md_png, "","Load Mega Drive/Genesis games", 278,141,84, 92}, + {NULL,Load_cd_png, "","Load Sega/Mega CD games", 454,141,64, 92}, + {NULL,Load_ms_png, "","Load Master System games", 114,284,84, 96}, + {NULL,Load_gg_png, "","Load Game Gear games", 278,283,84,100}, + {NULL,Load_sg_png, "","Load SG-1000 games", 454,281,64, 96} +}; + +/* Option menu */ +static gui_item items_options[5] = +{ + {NULL,Option_system_png,"","System settings", 114,142,80,92}, + {NULL,Option_video_png, "","Video settings", 288,150,64,84}, + {NULL,Option_sound_png, "","Audio settings", 464,154,44,80}, + {NULL,Option_ctrl_png, "","Controllers settings", 192,286,88,92}, + {NULL,Option_menu_png, "","Menu settings", 370,286,60,92} +}; + +/* Audio options */ +static gui_item items_audio[13] = +{ + {NULL,NULL,"Master System FM: AUTO", "Enable/disable YM2413 chip", 56,132,276,48}, + {NULL,NULL,"High-Quality FM: ON", "Adjust YM2612/YM2413 resampling quality", 56,132,276,48}, + {NULL,NULL,"FM Resolution: MAX", "Adjust YM2612 DAC precision", 56,132,276,48}, + {NULL,NULL,"FM Volume: 1.00", "Adjust YM2612/YM2413 output level", 56,132,276,48}, + {NULL,NULL,"PSG Volume: 2.50", "Adjust SN76489 output level", 56,132,276,48}, + {NULL,NULL,"PSG Noise Boost: OFF", "Boost SN76489 Noise Channel", 56,132,276,48}, + {NULL,NULL,"Audio Out: STEREO", "Select audio mixing output type", 56,132,276,48}, + {NULL,NULL,"Filtering: 3-BAND EQ", "Setup Audio filtering", 56,132,276,48}, + {NULL,NULL,"Low Gain: 1.00", "Adjust EQ Low Band Gain", 56,132,276,48}, + {NULL,NULL,"Mid Gain: 1.00", "Adjust EQ Mid Band Gain", 56,132,276,48}, + {NULL,NULL,"High Gain: 1.00", "Adjust EQ High Band Gain", 56,132,276,48}, + {NULL,NULL,"Low Freq: 200 Hz", "Adjust EQ Lowest Frequency", 56,132,276,48}, + {NULL,NULL,"High Freq: 20000 Hz", "Adjust EQ Highest Frequency", 56,132,276,48} +}; + +/* System options */ +static gui_item items_system[10] = +{ + {NULL,NULL,"Console Hardware: AUTO", "Select system hardware model", 56,132,276,48}, + {NULL,NULL,"Console Region: AUTO", "Select system region", 56,132,276,48}, + {NULL,NULL,"VDP Mode: AUTO", "Select VDP mode", 56,132,276,48}, + {NULL,NULL,"System Clock: AUTO", "Select system clock frequency", 56,132,276,48}, + {NULL,NULL,"System Boot: BIOS&CART", "Select system booting method", 56,132,276,48}, + {NULL,NULL,"System Lockups: ON", "Enable/disable original system lock-ups", 56,132,276,48}, + {NULL,NULL,"68k Address Error: ON", "Enable/disable 68k address error exceptions", 56,132,276,48}, + {NULL,NULL,"Lock-on: OFF", "Select Lock-On cartridge type", 56,132,276,48}, + {NULL,NULL,"Cartridge Swap: OFF", "Enable/disable cartridge hot swap", 56,132,276,48}, + {NULL,NULL,"SVP Cycles: 1500", "Adjust SVP chip emulation speed", 56,132,276,48} +}; + +/* Video options */ +#ifdef HW_RVL +static gui_item items_video[13] = +#else +static gui_item items_video[11] = +#endif +{ + {NULL,NULL,"Display: PROGRESSIVE", "Select video mode", 56,132,276,48}, + {NULL,NULL,"TV mode: 50/60Hz", "Select video refresh rate", 56,132,276,48}, + {NULL,NULL,"VSYNC: AUTO", "Enable/disable sync with Video Hardware", 56,132,276,48}, + {NULL,NULL,"GX Bilinear Filter: OFF", "Enable/disable texture hardware filtering", 56,132,276,48}, + {NULL,NULL,"GX Deflickering Filter: OFF","Enable/disable GX hardware filtering", 56,132,276,48}, +#ifdef HW_RVL + {NULL,NULL,"VI Trap Filter: ON", "Enable/disable video hardware filtering", 56,132,276,48}, + {NULL,NULL,"VI Gamma Correction: 1.0", "Adjust video hardware gamma correction", 56,132,276,48}, +#endif + {NULL,NULL,"NTSC Filter: COMPOSITE", "Enable/disable NTSC software filtering", 56,132,276,48}, + {NULL,NULL,"Borders: OFF", "Enable/disable overscan emulation", 56,132,276,48}, + {NULL,NULL,"GG screen: ORIGINAL", "Enable/disable Game Gear extended screen", 56,132,276,48}, + {NULL,NULL,"Aspect: ORIGINAL (4:3)", "Select display aspect ratio", 56,132,276,48}, + {NULL,NULL,"Screen Position (+0,+0)", "Adjust display position", 56,132,276,48}, + {NULL,NULL,"Screen Scaling (+0,+0)", "Adjust display scaling", 56,132,276,48} +}; + +/* Menu options */ +static gui_item items_prefs[11] = +{ + {NULL,NULL,"Auto ROM Load: OFF", "Enable/disable automatic ROM loading on startup", 56,132,276,48}, + {NULL,NULL,"Auto Cheats: OFF", "Enable/disable automatic cheats activation", 56,132,276,48}, + {NULL,NULL,"Auto Saves: OFF", "Enable/disable automatic saves", 56,132,276,48}, + {NULL,NULL,"ROM Load Device: SD", "Configure default device for ROM files", 56,132,276,48}, + {NULL,NULL,"Saves Device: FAT", "Configure default device for Save files", 56,132,276,48}, + {NULL,NULL,"SFX Volume: 100", "Adjust sound effects volume", 56,132,276,48}, + {NULL,NULL,"BGM Volume: 100", "Adjust background music volume", 56,132,276,48}, + {NULL,NULL,"BG Overlay: ON", "Enable/disable background overlay", 56,132,276,48}, + {NULL,NULL,"Screen Width: 658", "Adjust menu screen width in pixels", 56,132,276,48}, + {NULL,NULL,"Show CD Leds: OFF", "Enable/disable CD leds display", 56,132,276,48}, + {NULL,NULL,"Show FPS: OFF", "Enable/disable FPS counter", 56,132,276,48}, +}; + +/* Save Manager */ +static gui_item items_saves[9] = +{ + {NULL,NULL,"","" ,0,0,0,0}, + {NULL,NULL,"","" ,0,0,0,0}, + {NULL,NULL,"","" ,0,0,0,0}, + {NULL,NULL,"","" ,0,0,0,0}, + {NULL,NULL,"","" ,0,0,0,0}, + {NULL,NULL,"","Load file" ,0,0,0,0}, + {NULL,NULL,"","Set as default file",0,0,0,0}, + {NULL,NULL,"","Delete file" ,0,0,0,0}, + {NULL,NULL,"","Save file" ,0,0,0,0} +}; + +/*****************************************************************************/ +/* Menu Buttons description */ +/*****************************************************************************/ + +/* Generic Buttons for list menu */ +static gui_butn arrow_up = {&arrow_up_data,BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,0,0,0},14,76,360,32}; +static gui_butn arrow_down = {&arrow_down_data,BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,0,0,0},14,368,360,32}; + +/* Generic list menu */ +static gui_butn buttons_list[4] = +{ + {&button_text_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},56,132,276,48}, + {&button_text_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},56,188,276,48}, + {&button_text_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},56,244,276,48}, + {&button_text_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},56,300,276,48} +}; + +/* Main menu */ +static gui_butn buttons_main[10] = +{ + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,0,1}, 80,140,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,1,1},246,140,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,1,0},412,140,148,132}, + {&button_icon_data, BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,4,0,1}, 80,194,148,132}, + {&button_icon_data, BUTTON_OVER_SFX ,{3,4,1,1},246,194,148,132}, + {&button_icon_data, BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,3,1,0},412,194,148,132}, + {NULL , BUTTON_OVER_SFX ,{3,1,0,2}, 10,334, 84, 32}, + {NULL , BUTTON_OVER_SFX ,{4,0,0,2}, 10,372, 84, 32}, + {NULL , BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,1,1,0},546,334, 84, 32}, + {NULL , BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0,2,0},546,372, 84, 32} +}; + +/* Controllers Menu */ +static gui_butn buttons_ctrls[13] = +{ + {&button_icon_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX ,{0,1,0,2}, 60, 88,148,132}, + {&button_icon_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX ,{1,0,0,5}, 60,258,148,132}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,1,2,0},250, 79, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,3,0},250,117, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,4,0},250,155, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,5,0},250,193, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,5,0},250,249, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,6,0},250,287, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,7,0},250,325, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0,8,0},250,363, 84, 32}, + {&button_icon_sm_data ,BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX ,{0,1,1,0},436,168,160, 52}, + {&button_icon_sm_data ,BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX ,{1,1,0,0},436,232,160, 52}, + {&button_icon_sm_data ,BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX|BUTTON_SELECT_SFX ,{1,0,0,0},436,296,160, 52} +}; + +/* Load Game menu */ +static gui_butn buttons_load[6] = +{ + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,0,1}, 80,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,1,1},246,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,1,0},412,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,0,1}, 80,264,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,1,1},246,264,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,1,0},412,264,148,132} +}; + +/* Options menu */ +static gui_butn buttons_options[5] = +{ + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,0,1}, 80,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,1,1},246,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,2,1,1},412,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,1,1},162,264,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,0,1,0},330,264,148,132} +}; + +/* Save Manager Menu */ +static gui_butn buttons_saves[9] = +{ + {&button_text_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,1,0,0}, 56,102,276,48}, + {&button_text_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0}, 56,158,276,48}, + {&button_text_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0}, 56,214,276,48}, + {&button_text_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0}, 56,270,276,48}, + {&button_text_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,0,0,0}, 56,326,276,48}, + {&button_load_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{0,1,0,0},530,130, 56,56}, + {&button_special_data,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{1,1,0,0},530,196, 56,56}, + {&button_delete_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{1,1,0,0},530,262, 56,56}, + {&button_save_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{1,0,0,0},530,328, 56,56} +}; + +/*****************************************************************************/ +/* Menu descriptions */ +/*****************************************************************************/ + +/* Main menu */ +static gui_menu menu_main = +{ + "", + 0,0, + 10,10,4,0, + items_main, + buttons_main, + bg_main, + {NULL,NULL}, + {NULL,NULL}, + NULL +}; + +/* Main menu */ +gui_menu menu_ctrls = +{ + "Controller Settings", + 0,0, + 13,13,8,0, + items_ctrls, + buttons_ctrls, + bg_ctrls, + {&action_cancel, &action_select}, + {NULL,NULL}, + ctrlmenu_cb +}; + +/* Load Game menu */ +static gui_menu menu_load = +{ + "Load Game", + 0,0, + 6,6,5,0, + items_load, + buttons_load, + bg_misc, + {&action_cancel, &action_select}, + {NULL,NULL}, + NULL +}; + +/* Options menu */ +static gui_menu menu_options = +{ + "Settings", + 0,0, + 5,5,5,0, + items_options, + buttons_options, + bg_misc, + {&action_cancel, &action_select}, + {NULL,NULL}, + NULL +}; + +/* System Options menu */ +static gui_menu menu_system = +{ + "System Settings", + 0,0, + 10,4,6,0, + items_system, + buttons_list, + bg_list, + {&action_cancel, &action_select}, + {&arrow_up,&arrow_down}, + NULL +}; + +/* Video Options menu */ +static gui_menu menu_video = +{ + "Video Settings", + 0,0, + 10,4,6,0, + items_video, + buttons_list, + bg_list, + {&action_cancel, &action_select}, + {&arrow_up,&arrow_down}, + NULL +}; + +/* Sound Options menu */ +static gui_menu menu_audio = +{ + "Audio Settings", + 0,0, + 9,4,6,0, + items_audio, + buttons_list, + bg_list, + {&action_cancel, &action_select}, + {&arrow_up,&arrow_down}, + NULL +}; + +/* Sound Options menu */ +static gui_menu menu_prefs = +{ + "Menu Settings", + 0,0, + 11,4,6,0, + items_prefs, + buttons_list, + bg_list, + {&action_cancel, &action_select}, + {&arrow_up,&arrow_down}, + NULL +}; + + +/* Save Manager menu */ +static gui_menu menu_saves = +{ + "Save Manager", + 0,0, + 9,9,8,0, + items_saves, + buttons_saves, + bg_saves, + {&action_cancel, &action_select}, + {NULL,NULL}, + savemenu_cb +}; + +/**************************************************************************** + * GUI Settings menu + * + ****************************************************************************/ +static void update_screen_w(void) +{ + vmode->viWidth = config.screen_w; + vmode->viXOrigin = (VI_MAX_WIDTH_NTSC -config.screen_w)/2; + VIDEO_Configure(vmode); + VIDEO_Flush(); +} + +static void update_bgm(void) +{ + SetVolumeOgg(((int)config.bgm_volume * 255) / 100); +} + +static void prefmenu () +{ + int ret, quit = 0; + gui_menu *m = &menu_prefs; + gui_item *items = m->items; + + sprintf (items[0].text, "Auto ROM Load: %s", config.autoload ? "ON":"OFF"); + sprintf (items[1].text, "Auto Cheats: %s", config.autocheat ? "ON":"OFF"); + if (config.s_auto == 3) sprintf (items[2].text, "Auto Saves: ALL"); + else if (config.s_auto == 2) sprintf (items[2].text, "Auto Saves: STATE ONLY"); + else if (config.s_auto == 1) sprintf (items[2].text, "Auto Saves: SRAM ONLY"); + else sprintf (items[2].text, "Auto Saves: NONE"); +#ifdef HW_RVL + if (config.l_device == 1) sprintf (items[3].text, "ROM Load Device: USB"); + else if (config.l_device == 2) sprintf (items[3].text, "ROM Load Device: DVD"); +#else + if (config.l_device == 1) sprintf (items[3].text, "ROM Load Device: DVD"); +#endif + else sprintf (items[3].text, "ROM Load Device: SD"); + if (config.s_device == 1) sprintf (items[4].text, "Saves Device: MCARD A"); + else if (config.s_device == 2) sprintf (items[4].text, "Saves Device: MCARD B"); + else sprintf (items[4].text, "Saves Device: FAT"); + sprintf (items[5].text, "SFX Volume: %1.1f", config.sfx_volume); + sprintf (items[6].text, "BGM Volume: %1.1f", config.bgm_volume); + sprintf (items[7].text, "BG Overlay: %s", config.bg_overlay ? "ON":"OFF"); + sprintf (items[8].text, "Screen Width: %d", config.screen_w); + sprintf (items[9].text, "Show CD Leds: %s", config.cd_leds ? "ON":"OFF"); + sprintf (items[10].text, "Show FPS: %s", config.fps ? "ON":"OFF"); + + GUI_InitMenu(m); + GUI_SlideMenuTitle(m,strlen("Menu ")); + + while (quit == 0) + { + ret = GUI_RunMenu(m); + + switch (ret) + { + case 0: /* Auto load last ROM file on startup */ + config.autoload ^= 1; + sprintf (items[0].text, "Auto ROM Load: %s", config.autoload ? "ON":"OFF"); + break; + + case 1: /* Cheats automatic activation */ + config.autocheat ^= 1; + sprintf (items[1].text, "Auto Cheats: %s", config.autocheat ? "ON":"OFF"); + break; + + case 2: /*** Auto load/save STATE & SRAM files ***/ + config.s_auto = (config.s_auto + 1) % 4; + if (config.s_auto == 3) sprintf (items[2].text, "Auto Saves: ALL"); + else if (config.s_auto == 2) sprintf (items[2].text, "Auto Saves: STATE ONLY"); + else if (config.s_auto == 1) sprintf (items[2].text, "Auto Saves: SRAM ONLY"); + else sprintf (items[2].text, "Auto Saves: NONE"); + break; + + case 3: /*** Default ROM device ***/ +#ifdef HW_RVL + config.l_device = (config.l_device + 1) % 3; + if (config.l_device == 1) sprintf (items[3].text, "ROM Load Device: USB"); + else if (config.l_device == 2) sprintf (items[3].text, "ROM Load Device: DVD"); +#else + config.l_device ^= 1; + if (config.l_device == 1) sprintf (items[3].text, "ROM Load Device: DVD"); +#endif + else sprintf (items[3].text, "ROM Load Device: SD"); + break; + + case 4: /*** Default saves device ***/ + config.s_device = (config.s_device + 1) % 3; + if (config.s_device == 1) sprintf (items[4].text, "Saves Device: MCARD A"); + else if (config.s_device == 2) sprintf (items[4].text, "Saves Device: MCARD B"); + else sprintf (items[4].text, "Saves Device: FAT"); + break; + + case 5: /*** Sound effects volume ***/ + GUI_OptionBox(m,0,"SFX Volume",(void *)&config.sfx_volume,10.0,0.0,100.0,0); + sprintf (items[5].text, "SFX Volume: %1.1f", config.sfx_volume); + break; + + case 6: /*** Background music volume ***/ + GUI_OptionBox(m,update_bgm,"BGM Volume",(void *)&config.bgm_volume,10.0,0.0,100.0,0); + sprintf (items[6].text, "BGM Volume: %1.1f", config.bgm_volume); + break; + + case 7: /*** Background overlay ***/ + config.bg_overlay ^= 1; + if (config.bg_overlay) + { + bg_main[1].state |= IMAGE_VISIBLE; + bg_misc[1].state |= IMAGE_VISIBLE; + bg_ctrls[1].state |= IMAGE_VISIBLE; + bg_list[1].state |= IMAGE_VISIBLE; + bg_saves[2].state |= IMAGE_VISIBLE; + sprintf (items[7].text, "BG Overlay: ON"); + } + else + { + bg_main[1].state &= ~IMAGE_VISIBLE; + bg_misc[1].state &= ~IMAGE_VISIBLE; + bg_ctrls[1].state &= ~IMAGE_VISIBLE; + bg_list[1].state &= ~IMAGE_VISIBLE; + bg_saves[2].state &= ~IMAGE_VISIBLE; + sprintf (items[7].text, "BG Overlay: OFF"); + } + break; + + case 8: /*** Screen Width ***/ + GUI_OptionBox(m,update_screen_w,"Screen Width",(void *)&config.screen_w,2,640,VI_MAX_WIDTH_NTSC,1); + sprintf (items[8].text, "Screen Width: %d", config.screen_w); + break; + + case 9: /*** CD LEDS ***/ + config.cd_leds ^= 1; + sprintf (items[9].text, "Show CD Leds: %s", config.cd_leds ? "ON":"OFF"); + break; + + case 10: /*** FPS counter ***/ + config.fps ^= 1; + sprintf (items[10].text, "Show FPS: %s", config.fps ? "ON":"OFF"); + break; + + case -1: + quit = 1; + break; + } + } + + /* stop DVD drive when not in use */ + if (config.l_device != 2) + { +#ifdef HW_RVL + DI_StopMotor(); +#else + vu32* const dvd = (u32*)0xCC006000; + dvd[0] = 0x2e; + dvd[1] = 0; + dvd[2] = 0xe3000000; + dvd[3] = 0; + dvd[4] = 0; + dvd[5] = 0; + dvd[6] = 0; + dvd[7] = 1; + while (dvd[7] & 1); + dvd[0] = 0x14; + dvd[1] = 0; +#endif + } + + GUI_DeleteMenu(m); +} + +/**************************************************************************** + * Audio Settings menu + * + ****************************************************************************/ +static void soundmenu () +{ + int ret, quit = 0; + float fm_volume = (float)config.fm_preamp/100.0; + float psg_volume = (float)config.psg_preamp/100.0; + gui_menu *m = &menu_audio; + gui_item *items = m->items; + + if (config.ym2413 == 0) sprintf (items[0].text, "Master System FM: OFF"); + else if (config.ym2413 == 1) sprintf (items[0].text, "Master System FM: ON"); + else sprintf (items[0].text, "Master System FM: AUTO"); + + if (config.hq_fm) sprintf (items[1].text, "High-Quality FM: ON"); + else sprintf (items[1].text, "High-Quality FM: OFF"); + + if (config.dac_bits < 14) sprintf (items[2].text, "FM Resolution: %d bits", config.dac_bits); + else sprintf (items[2].text, "FM Resolution: MAX"); + + sprintf (items[3].text, "FM Volume: %1.2f", fm_volume); + sprintf (items[4].text, "PSG Volume: %1.2f", psg_volume); + sprintf (items[5].text, "PSG Noise Boost: %s", config.psgBoostNoise ? "ON":"OFF"); + sprintf (items[6].text, "Audio Out: %s", config.mono ? "MONO":"STEREO"); + + if (config.filter == 2) + { + float lg = (float)config.lg/100.0; + float mg = (float)config.mg/100.0; + float hg = (float)config.hg/100.0; + + sprintf(items[7].text, "Filtering: 3-BAND EQ"); + sprintf(items[8].text, "Low Gain: %1.2f", lg); + strcpy(items[8].comment, "Adjust EQ Low Band Gain"); + sprintf(items[9].text, "Middle Gain: %1.2f", mg); + sprintf(items[10].text, "High Gain: %1.2f", hg); + sprintf(items[11].text, "Low Freq: %d", config.low_freq); + sprintf(items[12].text, "High Freq: %d", config.high_freq); + m->max_items = 13; + } + else if (config.filter == 1) + { + int16 lp_range = (config.lp_range * 100 + 0xffff) / 0x10000; + sprintf (items[7].text, "Filtering: LOW-PASS"); + sprintf (items[8].text, "Low-Pass Rate: %d %%", lp_range); + strcpy (items[9].comment, "Adjust Low Pass filter"); + m->max_items = 9; + } + else + { + sprintf (items[7].text, "Filtering: OFF"); + m->max_items = 8; + } + + GUI_InitMenu(m); + GUI_SlideMenuTitle(m,strlen("Audio ")); + + while (quit == 0) + { + ret = GUI_RunMenu(m); + + switch (ret) + { + case 0: + { + config.ym2413++; + if (config.ym2413 > 2) config.ym2413 = 0; + if (config.ym2413 == 0) sprintf (items[0].text, "Master System FM: OFF"); + else if (config.ym2413 == 1) sprintf (items[0].text, "Master System FM: ON"); + else sprintf (items[0].text, "Master System FM: AUTO"); + + /* Automatic detection */ + if ((config.ym2413 & 2) && system_hw && ((system_hw & SYSTEM_PBC) != SYSTEM_MD)) + { + /* detect if game is using YM2413 */ + sms_cart_init(); + + /* restore SRAM */ + slot_autoload(0,config.s_device); + } + break; + } + + case 1: + { + config.hq_fm ^= 1; + if (config.hq_fm) sprintf (items[1].text, "High-Quality FM: ON"); + else sprintf (items[1].text, "High-Quality FM: OFF"); + break; + } + + case 2: + { + config.dac_bits++; + if (config.dac_bits > 14) config.dac_bits = 7; + if (config.dac_bits < 14) sprintf (items[2].text, "FM Resolution: %d bits", config.dac_bits); + else sprintf (items[2].text, "FM Resolution: MAX"); + YM2612Config(config.dac_bits); + break; + } + + case 3: + { + GUI_OptionBox(m,0,"FM Volume",(void *)&fm_volume,0.01,0.0,5.0,0); + sprintf (items[3].text, "FM Volume: %1.2f", fm_volume); + config.fm_preamp = (int)(fm_volume * 100.0 + 0.5); + break; + } + + case 4: + { + GUI_OptionBox(m,0,"PSG Volume",(void *)&psg_volume,0.01,0.0,5.0,0); + sprintf (items[4].text, "PSG Volume: %1.2f", psg_volume); + config.psg_preamp = (int)(psg_volume * 100.0 + 0.5); + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff); + } + else + { + SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, io_reg[6]); + } + break; + } + + case 5: + { + config.psgBoostNoise ^= 1; + sprintf (items[5].text, "PSG Noise Boost: %s", config.psgBoostNoise ? "ON":"OFF"); + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff); + } + else + { + SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, io_reg[6]); + } + break; + } + + case 6: + { + config.mono ^= 1; + sprintf (items[6].text, "Audio Out: %s", config.mono ? "MONO":"STEREO"); + break; + } + + case 7: + { + config.filter = (config.filter + 1) % 3; + if (config.filter == 2) + { + float lg = (float)config.lg/100.0; + sprintf (items[7].text, "Filtering: 3-BAND EQ"); + sprintf (items[8].text, "Low Gain: %1.2f", lg); + strcpy (items[8].comment, "Adjust EQ Low Band Gain"); + m->max_items = 13; + audio_set_equalizer(); + } + else if (config.filter == 1) + { + int lp_range = (config.lp_range * 100 + 0xffff) / 0x10000; + sprintf (items[7].text, "Filtering: LOW-PASS"); + sprintf (items[8].text, "Low-Pass Rate: %d %%", lp_range); + strcpy (items[8].comment, "Adjust Low Pass filter"); + m->max_items = 9; + } + else + { + sprintf (items[7].text, "Filtering: OFF"); + m->max_items = 8; + } + + while ((m->offset + 4) > m->max_items) + { + m->offset--; + m->selected++; + } + break; + } + + case 8: + { + if (config.filter == 1) + { + int16 lp_range = (config.lp_range * 100 + 0xffff) / 0x10000; + GUI_OptionBox(m,0,"Low-Pass Rate",(void *)&lp_range,1,0,100,1); + sprintf (items[8].text, "Low-Pass Rate: %d %%", lp_range); + config.lp_range = (lp_range * 0x10000) / 100; + } + else + { + float lg = (float)config.lg/100.0; + GUI_OptionBox(m,0,"Low Gain",(void *)&lg,0.01,0.0,2.0,0); + sprintf (items[8].text, "Low Gain: %1.2f", lg); + config.lg = (int)(lg * 100.0); + audio_set_equalizer(); + } + break; + } + + case 9: + { + float mg = (float)config.mg/100.0; + GUI_OptionBox(m,0,"Middle Gain",(void *)&mg,0.01,0.0,2.0,0); + sprintf (items[9].text, "Middle Gain: %1.2f", mg); + config.mg = (int)(mg * 100.0); + audio_set_equalizer(); + break; + } + + case 10: + { + float hg = (float)config.hg/100.0; + GUI_OptionBox(m,0,"High Gain",(void *)&hg,0.01,0.0,2.0,0); + sprintf (items[10].text, "High Gain: %1.2f", hg); + config.hg = (int)(hg * 100.0); + audio_set_equalizer(); + break; + } + + case 11: + { + GUI_OptionBox(m,0,"Low Frequency",(void *)&config.low_freq,10,0,config.high_freq,1); + sprintf (items[11].text, "Low Freq: %d", config.low_freq); + audio_set_equalizer(); + break; + } + + case 12: + { + GUI_OptionBox(m,0,"High Frequency",(void *)&config.high_freq,100,config.low_freq,30000,1); + sprintf (items[12].text, "High Freq: %d", config.high_freq); + audio_set_equalizer(); + break; + } + + case -1: + { + quit = 1; + break; + } + } + } + + GUI_DeleteMenu(m); +} + +/**************************************************************************** + * System Settings menu + * + ****************************************************************************/ +static const uint16 vc_table[4][2] = +{ + /* NTSC, PAL */ + {0xDA , 0xF2}, /* Mode 4 (192 lines) */ + {0xEA , 0x102}, /* Mode 5 (224 lines) */ + {0xDA , 0xF2}, /* Mode 4 (192 lines) */ + {0x106, 0x10A} /* Mode 5 (240 lines) */ +}; + +static void systemmenu () +{ + int ret, quit = 0; + int reinit = 0; + gui_menu *m = &menu_system; + gui_item *items = m->items; + + if (config.system == 0) + sprintf (items[0].text, "Console Type: AUTO"); + else if (config.system == SYSTEM_SG) + sprintf (items[0].text, "Console Type: SG-1000"); + else if (config.system == SYSTEM_MARKIII) + sprintf (items[0].text, "Console Type: MARK-III"); + else if (config.system == SYSTEM_SMS) + sprintf (items[0].text, "Console Type: SMS"); + else if (config.system == SYSTEM_SMS2) + sprintf (items[0].text, "Console Type: SMS II"); + else if (config.system == SYSTEM_GG) + sprintf (items[0].text, "Console Type: GG"); + else if (config.system == SYSTEM_MD) + sprintf (items[0].text, "Console Type: MD"); + + if (config.region_detect == 0) + sprintf (items[1].text, "Console Region: AUTO"); + else if (config.region_detect == 1) + sprintf (items[1].text, "Console Region: USA"); + else if (config.region_detect == 2) + sprintf (items[1].text, "Console Region: EUROPE"); + else if (config.region_detect == 3) + sprintf (items[1].text, "Console Region: JAPAN"); + + if (config.vdp_mode == 0) + sprintf (items[2].text, "VDP Mode: AUTO"); + else if (config.vdp_mode == 1) + sprintf (items[2].text, "VDP Mode: NTSC"); + else if (config.vdp_mode == 2) + sprintf (items[2].text, "VDP Mode: PAL"); + + if (config.master_clock == 0) + sprintf (items[3].text, "System Clock: AUTO"); + else if (config.master_clock == 1) + sprintf (items[3].text, "System Clock: NTSC"); + else if (config.master_clock == 2) + sprintf (items[3].text, "System Clock: PAL"); + + sprintf (items[4].text, "System Boot: %s", (config.bios & 1) ? ((config.bios & 2) ? "BIOS&CART" : "BIOS ONLY") : "CART"); + sprintf (items[5].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON"); + sprintf (items[6].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF"); + + if (config.lock_on == TYPE_GG) + sprintf (items[7].text, "Lock-On: GAME GENIE"); + else if (config.lock_on == TYPE_AR) + sprintf (items[7].text, "Lock-On: ACTION REPLAY"); + else if (config.lock_on == TYPE_SK) + sprintf (items[7].text, "Lock-On: SONIC&KNUCKLES"); + else + sprintf (items[7].text, "Lock-On: OFF"); + + sprintf (items[8].text, "Cartridge Swap: %s", (config.hot_swap & 1) ? "ON":"OFF"); + + if (svp) + { + sprintf (items[9].text, "SVP Cycles: %d", SVP_cycles); + m->max_items = 10; + } + else + { + m->max_items = 9; + } + + GUI_InitMenu(m); + GUI_SlideMenuTitle(m,strlen("System ")); + + while (quit == 0) + { + ret = GUI_RunMenu(m); + + switch (ret) + { + case 0: /*** Force System Hardware ***/ + { + if (config.system == SYSTEM_MD) + { + config.system = 0; + sprintf (items[0].text, "Console Type: AUTO"); + + /* Default system hardware (auto) */ + if (system_hw) system_hw = romtype; + } + else if (config.system == 0) + { + config.system = SYSTEM_SG; + sprintf (items[0].text, "Console Type: SG-1000"); + if (system_hw) system_hw = SYSTEM_SG; + } + else if (config.system == SYSTEM_SG) + { + config.system = SYSTEM_MARKIII; + sprintf (items[0].text, "Console Type: MARK-III"); + if (system_hw) system_hw = SYSTEM_MARKIII; + } + else if (config.system == SYSTEM_MARKIII) + { + config.system = SYSTEM_SMS; + sprintf (items[0].text, "Console Type: SMS"); + if (system_hw) system_hw = SYSTEM_SMS; + } + else if (config.system == SYSTEM_SMS) + { + config.system = SYSTEM_SMS2; + sprintf (items[0].text, "Console Type: SMS II"); + if (system_hw) system_hw = SYSTEM_SMS2; + } + else if (config.system == SYSTEM_SMS2) + { + config.system = SYSTEM_GG; + sprintf (items[0].text, "Console Type: GG"); + + if (romtype == SYSTEM_GG) + { + /* Game Gear mode */ + if (system_hw) system_hw = SYSTEM_GG; + } + else + { + /* Game Gear in MS compatibility mode */ + if (system_hw) system_hw = SYSTEM_GGMS; + } + } + else if (config.system == SYSTEM_GG) + { + config.system = SYSTEM_MD; + sprintf (items[0].text, "Console Type: MD"); + + if (romtype & SYSTEM_MD) + { + /* Default mode */ + if (system_hw) system_hw = romtype; + } + else + { + /* Mega Drive in MS compatibility mode */ + if (system_hw) system_hw = SYSTEM_PBC; + } + } + + if (system_hw) + { + /* restore previous input settings */ + if (old_system[0] != -1) + { + input.system[0] = old_system[0]; + } + if (old_system[1] != -1) + { + input.system[1] = old_system[1]; + } + + /* reinitialize audio streams */ + audio_init(snd.sample_rate, snd.frame_rate); + + /* force hard reset */ + system_init(); + system_reset(); + + /* restore SRAM */ + slot_autoload(0,config.s_device); + } + + break; + } + + case 1: /*** Force Region ***/ + { + config.region_detect = (config.region_detect + 1) % 4; + if (config.region_detect == 0) + sprintf (items[1].text, "Console Region: AUTO"); + else if (config.region_detect == 1) + sprintf (items[1].text, "Console Region: USA"); + else if (config.region_detect == 2) + sprintf (items[1].text, "Console Region: EUR"); + else if (config.region_detect == 3) + sprintf (items[1].text, "Console Region: JAPAN"); + + /* force system reinitialization + region BIOS */ + reinit = 2; + break; + } + + case 2: /*** Force VDP mode ***/ + { + config.vdp_mode = (config.vdp_mode + 1) % 3; + if (config.vdp_mode == 0) + sprintf (items[2].text, "VDP Mode: AUTO"); + else if (config.vdp_mode == 1) + sprintf (items[2].text, "VDP Mode: NTSC"); + else if (config.vdp_mode == 2) + sprintf (items[2].text, "VDP Mode: PAL"); + + /* force system reinitialization */ + reinit = 1; + break; + } + + case 3: /*** Force Master Clock ***/ + { + config.master_clock = (config.master_clock + 1) % 3; + if (config.master_clock == 0) + sprintf (items[3].text, "System Clock: AUTO"); + else if (config.master_clock == 1) + sprintf (items[3].text, "System Clock: NTSC"); + else if (config.master_clock == 2) + sprintf (items[3].text, "System Clock: PAL"); + + /* force system reinitialization */ + reinit = 1; + break; + } + + case 4: /*** BIOS support ***/ + { + if (config.bios == 0) config.bios = 3; + else if (config.bios == 3) config.bios = 1; + else config.bios = 0; + sprintf (items[4].text, "System Boot: %s", (config.bios & 1) ? ((config.bios & 2) ? "BIOS&CART " : "BIOS ONLY") : "CART"); + if ((system_hw == SYSTEM_MD) || (system_hw & SYSTEM_GG) || (system_hw & SYSTEM_SMS)) + { + /* force hard reset */ + system_init(); + system_reset(); + + /* restore SRAM */ + slot_autoload(0,config.s_device); + } + break; + } + + case 5: /*** force DTACK ***/ + { + config.force_dtack ^= 1; + sprintf (items[5].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON"); + break; + } + + case 6: /*** 68k Address Error ***/ + { + config.addr_error ^= 1; + m68k.aerr_enabled = config.addr_error; + sprintf (items[6].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF"); + break; + } + + case 7: /*** Cart Lock-On ***/ + { + config.lock_on = (config.lock_on + 1) % (TYPE_SK + 1); + if (config.lock_on == TYPE_GG) + sprintf (items[7].text, "Lock-On: GAME GENIE"); + else if (config.lock_on == TYPE_AR) + sprintf (items[7].text, "Lock-On: ACTION REPLAY"); + else if (config.lock_on == TYPE_SK) + sprintf (items[7].text, "Lock-On: SONIC&KNUCKLES"); + else + sprintf (items[7].text, "Lock-On: OFF"); + + if ((system_hw == SYSTEM_MD) || (system_hw == SYSTEM_PICO)) + { + /* force hard reset */ + system_init(); + system_reset(); + + /* restore SRAM */ + slot_autoload(0,config.s_device); + + /* Action Replay switch */ + if (areplay_get_status() < 0) + { + menu_main.buttons[6].state &= ~(BUTTON_VISIBLE | BUTTON_ACTIVE); + menu_main.items[6].data = NULL; + menu_main.cb = NULL; + menu_main.buttons[3].shift[1] = 4; + menu_main.buttons[7].shift[0] = 4; + menu_main.buttons[8].shift[2] = 1; + } + else + { + menu_main.buttons[6].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + menu_main.items[6].data = Button_sm_grey_png; + menu_main.cb = mainmenu_cb; + menu_main.buttons[3].shift[1] = 3; + menu_main.buttons[7].shift[0] = 1; + menu_main.buttons[8].shift[2] = 2; + } + } + break; + } + + case 8: /*** Cartridge Hot Swap ***/ + { + config.hot_swap ^= 1; + sprintf (items[8].text, "Cartridge Swap: %s", (config.hot_swap & 1) ? "ON":"OFF"); + break; + } + + case 9: /*** SVP cycles per line ***/ + { + GUI_OptionBox(m,0,"SVP Cycles",(void *)&SVP_cycles,1,1,1500,1); + sprintf (items[9].text, "SVP Cycles: %d", SVP_cycles); + break; + } + + case -1: + { + quit = 1; + break; + } + } + } + + if (reinit && system_hw) + { + /* reinitialize console region */ + get_region(NULL); + + /* framerate might have changed, reinitialize audio timings */ + audio_init(snd.sample_rate, get_framerate()); + + /* system with region BIOS should be reinitialized if region code has changed */ + if ((reinit & 2) && ((system_hw == SYSTEM_MCD) || ((system_hw & SYSTEM_SMS) && (config.bios & 1)))) + { + system_init(); + system_reset(); + + /* restore SRAM */ + slot_autoload(0,config.s_device); + } + else + { + /* reinitialize I/O region register */ + if (system_hw == SYSTEM_MD) + { + io_reg[0x00] = 0x20 | region_code | (config.bios & 1); + } + else if (system_hw == SYSTEM_MCD) + { + io_reg[0x00] = region_code | (config.bios & 1); + } + else + { + io_reg[0x00] = 0x80 | (region_code >> 1); + } + + /* reinitialize VDP */ + if (vdp_pal) + { + status |= 1; + lines_per_frame = 313; + } + else + { + status &= ~1; + lines_per_frame = 262; + } + + /* reinitialize VC max value */ + switch (bitmap.viewport.h) + { + case 192: + vc_max = vc_table[0][vdp_pal]; + break; + case 224: + vc_max = vc_table[1][vdp_pal]; + break; + case 240: + vc_max = vc_table[3][vdp_pal]; + break; + } + } + } + + GUI_DeleteMenu(m); +} + +/**************************************************************************** + * Video Settings menu + * + ****************************************************************************/ +#ifdef HW_RVL +#define VI_OFFSET 7 +static void update_gamma(void) +{ + VIDEO_SetGamma((int)(config.gamma * 10.0)); + VIDEO_Flush(); +} +#else +#define VI_OFFSET 5 +#endif + +static void videomenu () +{ + u16 state[2]; + int ret, quit = 0; + int reinit = 0; + gui_menu *m = &menu_video; + gui_item *items = m->items; + + if (config.render == 1) + sprintf (items[0].text,"Display: INTERLACED"); + else if (config.render == 2) + sprintf (items[0].text, "Display: PROGRESSIVE"); + else + sprintf (items[0].text, "Display: ORIGINAL"); + + if (config.tv_mode == 0) + sprintf (items[1].text, "TV Mode: 60HZ"); + else if (config.tv_mode == 1) + sprintf (items[1].text, "TV Mode: 50HZ"); + else + sprintf (items[1].text, "TV Mode: 50/60HZ"); + + if (config.vsync) + sprintf (items[2].text, "VSYNC: AUTO"); + else + sprintf (items[2].text, "VSYNC: OFF"); + + sprintf (items[3].text, "GX Bilinear Filter: %s", config.bilinear ? " ON" : "OFF"); + sprintf (items[4].text, "GX Deflickering Filter: %s", config.vfilter ? " ON" : "OFF"); + +#ifdef HW_RVL + sprintf (items[5].text, "VI Trap Filter: %s", config.trap ? " ON" : "OFF"); + sprintf (items[6].text, "VI Gamma Correction: %1.1f", config.gamma); +#endif + + if (config.ntsc == 1) + sprintf (items[VI_OFFSET].text, "NTSC Filter: COMPOSITE"); + else if (config.ntsc == 2) + sprintf (items[VI_OFFSET].text, "NTSC Filter: S-VIDEO"); + else if (config.ntsc == 3) + sprintf (items[VI_OFFSET].text, "NTSC Filter: RGB"); + else + sprintf (items[VI_OFFSET].text, "NTSC Filter: OFF"); + + if (config.overscan == 3) + sprintf (items[VI_OFFSET+1].text, "Borders: FULL"); + else if (config.overscan == 2) + sprintf (items[VI_OFFSET+1].text, "Borders: H ONLY"); + else if (config.overscan == 1) + sprintf (items[VI_OFFSET+1].text, "Borders: V ONLY"); + else + sprintf (items[VI_OFFSET+1].text, "Borders: NONE"); + + sprintf(items[VI_OFFSET+2].text, "GG Screen: %s", config.gg_extra ? "EXTENDED":"ORIGINAL"); + + if (config.aspect == 1) + sprintf (items[VI_OFFSET+3].text,"Aspect: ORIGINAL (4:3)"); + else if (config.aspect == 2) + sprintf (items[VI_OFFSET+3].text, "Aspect: ORIGINAL (16:9)"); + else + sprintf (items[VI_OFFSET+3].text, "Aspect: SCALED"); + + sprintf (items[VI_OFFSET+4].text, "Screen Position: (%s%02d,%s%02d)", + (config.xshift < 0) ? "":"+", config.xshift, + (config.yshift < 0) ? "":"+", config.yshift); + + sprintf (items[VI_OFFSET+5].text, "Screen Scaling: (%s%02d,%s%02d)", + (config.xscale < 0) ? "":"+", config.xscale, + (config.yscale < 0) ? "":"+", config.yscale); + + if (config.aspect) + m->max_items = VI_OFFSET+5; + else + m->max_items = VI_OFFSET+6; + + GUI_InitMenu(m); + GUI_SlideMenuTitle(m,strlen("Video ")); + + while (quit == 0) + { + ret = GUI_RunMenu(m); + + switch (ret) + { + case 0: /*** rendering ***/ + config.render = (config.render + 1) % 3; + if (config.render == 2) + { + /* progressive mode is only possible through component cable */ + if (!VIDEO_HaveComponentCable()) + { + config.render = 0; + } + } + if (config.render == 1) + sprintf (items[0].text,"Display: INTERLACED"); + else if (config.render == 2) + sprintf (items[0].text, "Display: PROGRESSIVE"); + else + sprintf (items[0].text, "Display: ORIGINAL"); + reinit = 1; + break; + + case 1: /*** tv mode ***/ + config.tv_mode = (config.tv_mode + 1) % 3; + if (config.tv_mode == 0) + sprintf (items[1].text, "TV Mode: 60HZ"); + else if (config.tv_mode == 1) + sprintf (items[1].text, "TV Mode: 50HZ"); + else + sprintf (items[1].text, "TV Mode: 50/60HZ"); + reinit = 1; + break; + + case 2: /*** VSYNC ***/ + config.vsync ^= 1; + if (config.vsync) + sprintf (items[2].text, "VSYNC: AUTO"); + else + sprintf (items[2].text, "VSYNC: OFF"); + reinit = 1; + break; + + case 3: /*** GX Texture filtering ***/ + config.bilinear ^= 1; + sprintf (items[3].text, "GX Bilinear Filter: %s", config.bilinear ? " ON" : "OFF"); + break; + + case 4: /*** GX Copy filtering (deflickering filter) ***/ + config.vfilter ^= 1; + sprintf (items[4].text, "GX Deflicker Filter: %s", config.vfilter ? " ON" : "OFF"); + break; + +#ifdef HW_RVL + case 5: /*** VIDEO Trap filtering ***/ + config.trap ^= 1; + sprintf (items[5].text, "VI Trap Filter: %s", config.trap ? " ON" : "OFF"); + break; + + case 6: /*** VIDEO Gamma correction ***/ + if (system_hw) + { + update_gamma(); + state[0] = m->arrows[0]->state; + state[1] = m->arrows[1]->state; + m->max_buttons = 0; + m->max_images = 0; + m->arrows[0]->state = 0; + m->arrows[1]->state = 0; + m->screenshot = 255; + strcpy(m->title,""); + GUI_OptionBox(m,update_gamma,"VI Gamma Correction",(void *)&config.gamma,0.1,0.1,3.0,0); + m->max_buttons = 4; + m->max_images = 6; + m->arrows[0]->state = state[0]; + m->arrows[1]->state = state[1]; + m->screenshot = 0; + strcpy(m->title,"Video Settings"); + sprintf (items[6].text, "VI Gamma Correction: %1.1f", config.gamma); + VIDEO_SetGamma(VI_GM_1_0); + VIDEO_Flush(); + } + else + { + GUI_WaitPrompt("Error","Please load a game first !\n"); + } + break; +#endif + + case VI_OFFSET: /*** NTSC filter ***/ + config.ntsc = (config.ntsc + 1) & 3; + if (config.ntsc == 1) + sprintf (items[VI_OFFSET].text, "NTSC Filter: COMPOSITE"); + else if (config.ntsc == 2) + sprintf (items[VI_OFFSET].text, "NTSC Filter: S-VIDEO"); + else if (config.ntsc == 3) + sprintf (items[VI_OFFSET].text, "NTSC Filter: RGB"); + else + sprintf (items[VI_OFFSET].text, "NTSC Filter: OFF"); + break; + + case VI_OFFSET+1: /*** overscan emulation ***/ + config.overscan = (config.overscan + 1) & 3; + if (config.overscan == 3) + sprintf (items[VI_OFFSET+1].text, "Borders: FULL"); + else if (config.overscan == 2) + sprintf (items[VI_OFFSET+1].text, "Borders: H ONLY"); + else if (config.overscan == 1) + sprintf (items[VI_OFFSET+1].text, "Borders: V ONLY"); + else + sprintf (items[VI_OFFSET+1].text, "Borders: NONE"); + break; + + case VI_OFFSET+2: /*** Game Gear extended screen */ + config.gg_extra ^= 1; + sprintf(items[VI_OFFSET+2].text, "GG Screen: %s", config.gg_extra ? "EXTENDED":"ORIGINAL"); + break; + + case VI_OFFSET+3: /*** aspect ratio ***/ + config.aspect = (config.aspect + 1) % 3; + if (config.aspect == 1) + sprintf (items[VI_OFFSET+3].text,"Aspect: ORIGINAL (4:3)"); + else if (config.aspect == 2) + sprintf (items[VI_OFFSET+3].text, "Aspect: ORIGINAL (16:9)"); + else + sprintf (items[VI_OFFSET+3].text, "Aspect: SCALED"); + + if (config.aspect) + { + /* disable items */ + m->max_items = VI_OFFSET+5; + + /* reset menu selection */ + if (m->offset > VI_OFFSET) + { + m->offset = VI_OFFSET; + m->selected = 3; + } + } + else + { + /* enable items */ + m->max_items = VI_OFFSET+6; + } + + break; + + case VI_OFFSET+4: /*** screen position ***/ + if (system_hw) + { + state[0] = m->arrows[0]->state; + state[1] = m->arrows[1]->state; + m->max_buttons = 0; + m->max_images = 0; + m->arrows[0]->state = 0; + m->arrows[1]->state = 0; + m->screenshot = 255; + strcpy(m->title,""); + GUI_OptionBox2(m,"X Offset","Y Offset",&config.xshift,&config.yshift,1,-99,99); + m->max_buttons = 4; + m->max_images = 6; + m->arrows[0]->state = state[0]; + m->arrows[1]->state = state[1]; + m->screenshot = 0; + strcpy(m->title,"Video Settings"); + sprintf (items[VI_OFFSET+4].text, "Screen Position: (%s%02d,%s%02d)", + (config.xshift < 0) ? "":"+", config.xshift, + (config.yshift < 0) ? "":"+", config.yshift); + } + else + { + GUI_WaitPrompt("Error","Please load a game first !\n"); + } + break; + + case VI_OFFSET+5: /*** screen scaling ***/ + if (system_hw) + { + state[0] = m->arrows[0]->state; + state[1] = m->arrows[1]->state; + m->max_buttons = 0; + m->max_images = 0; + m->arrows[0]->state = 0; + m->arrows[1]->state = 0; + m->screenshot = 255; + strcpy(m->title,""); + GUI_OptionBox2(m,"X Scale","Y Scale",&config.xscale,&config.yscale,1,-99,99); + m->max_buttons = 4; + m->max_images = 6; + m->arrows[0]->state = state[0]; + m->arrows[1]->state = state[1]; + m->screenshot = 0; + strcpy(m->title,"Video Settings"); + sprintf (items[VI_OFFSET+5].text, "Screen Scaling: (%s%02d,%s%02d)", + (config.xscale < 0) ? "":"+", config.xscale, + (config.yscale < 0) ? "":"+", config.yscale); + } + else + { + GUI_WaitPrompt("Error","Please load a game first !\n"); + } + break; + + case -1: + quit = 1; + break; + } + } + + if (reinit && system_hw) + { + /* framerate might have changed, reinitialize audio timings */ + audio_init(snd.sample_rate, get_framerate()); + } + + GUI_DeleteMenu(m); +} + +/**************************************************************************** + * Controllers Settings menu + ****************************************************************************/ +static int player = 0; +static void ctrlmenu_cb(void) +{ + int i, cnt = 1; + char msg[16]; + gui_menu *m = &menu_ctrls; + + if (m->bg_images[7].state & IMAGE_VISIBLE) + { + /* draw device port number */ + if (config.input[player].device != -1) + { + sprintf(msg,"%d",config.input[player].port + 1); + if (m->selected == 11) + FONT_write(msg,16,m->items[11].x+m->items[11].w+2,m->items[11].y+m->items[11].h+2,640,(GXColor)DARK_GREY); + else + FONT_write(msg,14,m->items[11].x+m->items[11].w,m->items[11].y+m->items[11].h,640,(GXColor)DARK_GREY); + } + } + + /* draw players index */ + for (i=2; iselected == i) + { + FONT_writeCenter("Player", 16, m->buttons[i].x + 2, m->buttons[i].x + 54, m->buttons[i].y + (m->buttons[i].h - 16)/2 + 16, (GXColor)DARK_GREY); + } + else + { + FONT_writeCenter("Player", 14, m->buttons[i].x + 4, m->buttons[i].x + 54, m->buttons[i].y + (m->buttons[i].h - 14)/2 + 14, (GXColor)DARK_GREY); + } + + if (input.dev[i-2] != NO_DEVICE) + { + sprintf(msg,"%d",cnt++); + if (m->selected == i) + { + FONT_writeCenter(msg,18,m->items[i].x+2,m->items[i].x+m->items[i].w+2,m->buttons[i].y+(m->buttons[i].h-18)/2+18,(GXColor)DARK_GREY); + } + else + { + FONT_writeCenter(msg,16,m->items[i].x,m->items[i].x+m->items[i].w,m->buttons[i].y+(m->buttons[i].h - 16)/2+16,(GXColor)DARK_GREY); + } + } + } +} + +/* Set menu elements depending on current system configuration */ +static void ctrlmenu_raz(void) +{ + int i,max = 0; + gui_menu *m = &menu_ctrls; + + /* update players buttons */ + for (i=0; ibuttons[i+2].data = &button_player_none_data; + m->buttons[i+2].state &= ~BUTTON_ACTIVE; + strcpy(m->items[i+2].comment,""); + } + else + { + m->buttons[i+2].data = &button_player_data; + m->buttons[i+2].state |= BUTTON_ACTIVE; + if ((cart.special & HW_J_CART) && (i > 4)) + sprintf(m->items[i+2].comment,"Configure Player %d (J-CART) settings", max + 1); + else + sprintf(m->items[i+2].comment,"Configure Player %d settings", max + 1); + max++; + } + } + + /* update buttons navigation */ + if (input.dev[0] != NO_DEVICE) + m->buttons[0].shift[3] = 2; + else if (input.dev[4] != NO_DEVICE) + m->buttons[0].shift[3] = 6; + else if (input.dev[5] != NO_DEVICE) + m->buttons[0].shift[3] = 7; + else + m->buttons[0].shift[3] = 0; + if (input.dev[4] != NO_DEVICE) + m->buttons[1].shift[3] = 5; + else if (input.dev[5] != NO_DEVICE) + m->buttons[1].shift[3] = 6; + else if (input.dev[0] != NO_DEVICE) + m->buttons[1].shift[3] = 1; + else + m->buttons[1].shift[3] = 0; + + if (input.dev[1] != NO_DEVICE) + m->buttons[2].shift[1] = 1; + else if (input.dev[4] != NO_DEVICE) + m->buttons[2].shift[1] = 4; + else if (input.dev[5] != NO_DEVICE) + m->buttons[2].shift[1] = 5; + else + m->buttons[2].shift[1] = 0; + + if (input.dev[4] != NO_DEVICE) + m->buttons[5].shift[1] = 1; + else if (input.dev[5] != NO_DEVICE) + m->buttons[5].shift[1] = 2; + else + m->buttons[5].shift[1] = 0; + + if (input.dev[3] != NO_DEVICE) + m->buttons[6].shift[0] = 1; + else if (input.dev[0] != NO_DEVICE) + m->buttons[6].shift[0] = 4; + else + m->buttons[6].shift[0] = 0; + + if (input.dev[5] != NO_DEVICE) + m->buttons[6].shift[1] = 1; + else + m->buttons[6].shift[1] = 0; + + if (input.dev[6] != NO_DEVICE) + m->buttons[7].shift[1] = 1; + else + m->buttons[7].shift[1] = 0; + + if (input.dev[7] != NO_DEVICE) + m->buttons[8].shift[1] = 1; + else + m->buttons[8].shift[1] = 0; + + if (input.dev[4] != NO_DEVICE) + m->buttons[7].shift[0] = 1; + else if (input.dev[3] != NO_DEVICE) + m->buttons[7].shift[0] = 2; + else if (input.dev[0] != NO_DEVICE) + m->buttons[7].shift[0] = 5; + else + m->buttons[7].shift[0] = 0; +} + +static void ctrlmenu(void) +{ + int old_player = -1; + int i = 0; + int update = 0; + gui_item *items = NULL; + u8 *special = NULL; + u32 exp; + u8 type = 0; + + /* System devices */ + gui_item items_sys[2][13] = + { + { + {NULL,Ctrl_none_png ,"","Select Port 1 device",110,130,48,72}, + {NULL,Ctrl_gamepad_md_png ,"","Select Port 1 device", 85,117,96,84}, + {NULL,Ctrl_mouse_png ,"","Select Port 1 device", 97,113,64,88}, + {NULL,Ctrl_menacer_png ,"","Select Port 1 device", 94,113,80,88}, + {NULL,Ctrl_justifiers_png ,"","Select Port 1 device", 88,117,80,84}, + {NULL,Ctrl_xe_a1p_png ,"","Select Port 1 device", 98,118,72,84}, + {NULL,Ctrl_activator_png ,"","Select Port 1 device", 94,121,72,80}, + {NULL,Ctrl_gamepad_ms_png ,"","Select Port 1 device", 91,125,84,76}, + {NULL,Ctrl_lightphaser_png,"","Select Port 1 device", 89,109,88,92}, + {NULL,Ctrl_paddle_png ,"","Select Port 1 device", 86,117,96,84}, + {NULL,Ctrl_sportspad_png ,"","Select Port 1 device", 95,117,76,84}, + {NULL,Ctrl_teamplayer_png ,"","Select Port 1 device", 94,109,80,92}, + {NULL,Ctrl_4wayplay_png ,"","Select Port 1 device", 98,110,72,92} + }, + { + {NULL,Ctrl_none_png ,"","Select Port 2 device",110,300,48,72}, + {NULL,Ctrl_gamepad_md_png ,"","Select Port 2 device", 85,287,96,84}, + {NULL,Ctrl_mouse_png ,"","Select Port 2 device", 97,283,64,88}, + {NULL,Ctrl_menacer_png ,"","Select Port 2 device", 94,283,80,88}, + {NULL,Ctrl_justifiers_png ,"","Select Port 2 device", 88,287,80,84}, + {NULL,Ctrl_xe_a1p_png ,"","Select Port 2 device", 98,288,72,84}, + {NULL,Ctrl_activator_png ,"","Select Port 2 device", 94,291,72,80}, + {NULL,Ctrl_gamepad_ms_png ,"","Select Port 2 device", 91,295,84,76}, + {NULL,Ctrl_lightphaser_png,"","Select Port 2 device", 89,279,88,92}, + {NULL,Ctrl_paddle_png ,"","Select Port 2 device", 86,287,96,84}, + {NULL,Ctrl_sportspad_png ,"","Select Port 2 device", 95,287,76,84}, + {NULL,Ctrl_teamplayer_png ,"","Select Port 2 device", 94,279,80,92}, + {NULL,Ctrl_4wayplay_png ,"","Select Port 2 device", 98,280,72,92} + } + }; + + /* Specific controller options */ + gui_item items_special[4][2] = + { + { + /* Gamepad option */ + {NULL,Ctrl_pad3b_png,"Pad\nType","Use 3-buttons Pad",528,180,44,28}, + {NULL,Ctrl_pad6b_png,"Pad\nType","Use 6-buttons Pad",528,180,44,28} + }, + { + /* Mouse option */ + {NULL,ctrl_option_off_png,"Invert\nMouse","Enable/Disable Y-Axis inversion",534,180,24,24}, + {NULL,ctrl_option_on_png ,"Invert\nMouse","Enable/Disable Y-Axis inversion",534,180,24,24}, + }, + { + /* Gun option */ + {NULL,ctrl_option_off_png,"Show\nCursor","Enable/Disable Lightgun cursor",534,180,24,24}, + {NULL,ctrl_option_on_png ,"Show\nCursor","Enable/Disable Lightgun cursor",534,180,24,24}, + }, + { + /* no option */ + {NULL,NULL,"No Option","",436,180,160,52}, + {NULL,NULL,"","",0,0,0,0}, + } + }; + + /* Player Configuration device items */ +#ifdef HW_RVL + gui_item items_device[5] = + { + {NULL,ctrl_option_off_png ,"Input\nDevice","Select Input Controller",534,244,24,24}, + {NULL,ctrl_gamecube_png ,"Input\nDevice","Select Input Controller",530,246,36,24}, + {NULL,ctrl_wiimote_png ,"Input\nDevice","Select Input Controller",526,250,40,12}, + {NULL,ctrl_nunchuk_png ,"Input\nDevice","Select Input Controller",532,242,32,32}, + {NULL,ctrl_classic_png ,"Input\nDevice","Select Input Controller",526,242,40,32}, + }; +#else + gui_item items_device[2] = + { + {NULL,ctrl_option_off_png ,"Input\nDevice","Select Input Controller",534,244,24,24}, + {NULL,ctrl_gamecube_png ,"Input\nDevice","Select Input Controller",530,246,36,24} + }; +#endif + + /* initialize menu */ + gui_menu *m = &menu_ctrls; + GUI_InitMenu(m); + + /* initialize custom buttons */ + button_player_data.texture[0] = gxTextureOpenPNG(button_player_data.image[0],0); + button_player_data.texture[1] = gxTextureOpenPNG(button_player_data.image[1],0); + button_player_none_data.texture[0] = gxTextureOpenPNG(button_player_none_data.image[0],0); + + /* initialize custom images */ + for (i=0; i<13; i++) + { + items_sys[1][i].texture = items_sys[0][i].texture = gxTextureOpenPNG(items_sys[0][i].data,0); + } + items_special[0][0].texture = gxTextureOpenPNG(items_special[0][0].data,0); + items_special[0][1].texture = gxTextureOpenPNG(items_special[0][1].data,0); + items_special[2][0].texture = items_special[1][0].texture = gxTextureOpenPNG(items_special[1][0].data,0); + items_special[2][1].texture = items_special[1][1].texture = gxTextureOpenPNG(items_special[1][1].data,0); + items_device[0].texture = items_special[1][0].texture; + items_device[1].texture = gxTextureOpenPNG(items_device[1].data,0); +#ifdef HW_RVL + items_device[2].texture = gxTextureOpenPNG(items_device[2].data,0); + items_device[3].texture = gxTextureOpenPNG(items_device[3].data,0); + items_device[4].texture = gxTextureOpenPNG(items_device[4].data,0); +#endif + + /* restore current menu elements */ + player = 0; + ctrlmenu_raz(); + memcpy(&m->items[0],&items_sys[0][input.system[0]],sizeof(gui_item)); + memcpy(&m->items[1],&items_sys[1][input.system[1]],sizeof(gui_item)); + + /* menu title slide effect */ + m->selected = 0; + GUI_SlideMenuTitle(m,strlen("Controller ")); + + while (update != -1) + { + /* draw menu */ + GUI_DrawMenu(m); + + /* update menu */ + update = GUI_UpdateMenu(m); + + if (update > 0) + { + switch (m->selected) + { + case 0: /* update port 1 system */ + { + /* fixed configurations */ + if (system_hw) + { + if (cart.special & HW_TEREBI_OEKAKI) + { + GUI_WaitPrompt("Error","Terebi Oekaki detected !"); + break; + } + else if (system_hw == SYSTEM_PICO) + { + GUI_WaitPrompt("Error","PICO hardware detected !"); + break; + } + } + + /* next connected device */ + input.system[0]++; + + /* allow only one connected mouse */ + if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE)) + { + input.system[0] += 3; + } + + /* Menacer & Justifiers on Port B only */ + if (input.system[0] == SYSTEM_MENACER) + { + input.system[0] += 2; + } + + /* allow only one gun type */ + if ((input.system[0] == SYSTEM_LIGHTPHASER) && ((input.system[1] == SYSTEM_MENACER) || (input.system[1] == SYSTEM_JUSTIFIER))) + { + input.system[0]++; + } + + /* 4-wayplay uses both ports */ + if (input.system[0] == SYSTEM_WAYPLAY) + { + input.system[1] = SYSTEM_WAYPLAY; + } + + /* loop back */ + if (input.system[0] > SYSTEM_WAYPLAY) + { + input.system[0] = NO_SYSTEM; + input.system[1] = SYSTEM_MD_GAMEPAD; + } + + /* reset I/O ports */ + io_init(); + input_reset(); + + /* save current configuration */ + old_system[0] = input.system[0]; + old_system[1] = input.system[1]; + + /* update menu elements */ + ctrlmenu_raz(); + memcpy(&m->items[0],&items_sys[0][input.system[0]],sizeof(gui_item)); + memcpy(&m->items[1],&items_sys[1][input.system[1]],sizeof(gui_item)); + + if (m->bg_images[7].state & IMAGE_VISIBLE) + { + /* slide out configuration window */ + GUI_DrawMenuFX(m, 20, 1); + + /* remove configuration window */ + m->bg_images[7].state &= ~IMAGE_VISIBLE; + + /* disable configuration buttons */ + m->buttons[10].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + m->buttons[11].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + m->buttons[12].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + + /* update directions */ + m->buttons[2].shift[3] = 0; + m->buttons[3].shift[3] = 0; + m->buttons[4].shift[3] = 0; + m->buttons[5].shift[3] = 0; + m->buttons[6].shift[3] = 0; + m->buttons[7].shift[3] = 0; + m->buttons[8].shift[3] = 0; + m->buttons[9].shift[3] = 0; + + /* update title */ + sprintf(m->title,"Controller Settings"); + } + break; + } + + case 1: /* update port 2 system */ + { + /* fixed configurations */ + if (system_hw) + { + if (cart.special & HW_J_CART) + { + GUI_WaitPrompt("Error","J-CART detected !"); + break; + } + else if (cart.special & HW_TEREBI_OEKAKI) + { + GUI_WaitPrompt("Error","Terebi Oekaki detected !"); + break; + } + else if (system_hw == SYSTEM_PICO) + { + GUI_WaitPrompt("Error","PICO hardware detected !"); + break; + } + } + + /* next connected device */ + input.system[1]++; + + /* allow only one connected mouse */ + if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE)) + { + input.system[1]++; + } + + /* allow only one gun type */ + if ((input.system[0] == SYSTEM_LIGHTPHASER) && (input.system[1] == SYSTEM_MENACER)) + { + input.system[1] += 3; + } + + /* allow only one gun type */ + if ((input.system[0] == SYSTEM_LIGHTPHASER) && (input.system[1] == SYSTEM_JUSTIFIER)) + { + input.system[1] += 2; + } + + /* 4-wayplay uses both ports */ + if (input.system[1] == SYSTEM_WAYPLAY) + { + input.system[0] = SYSTEM_WAYPLAY; + } + + /* loop back */ + if (input.system[1] > SYSTEM_WAYPLAY) + { + input.system[1] = NO_SYSTEM; + input.system[0] = SYSTEM_MD_GAMEPAD; + } + + /* reset I/O ports */ + io_init(); + input_reset(); + + /* save current configuration */ + old_system[0] = input.system[0]; + old_system[1] = input.system[1]; + + /* update menu elements */ + ctrlmenu_raz(); + memcpy(&m->items[0],&items_sys[0][input.system[0]],sizeof(gui_item)); + memcpy(&m->items[1],&items_sys[1][input.system[1]],sizeof(gui_item)); + + if (m->bg_images[7].state & IMAGE_VISIBLE) + { + /* slide out configuration window */ + GUI_DrawMenuFX(m, 20, 1); + + /* remove configuration window */ + m->bg_images[7].state &= ~IMAGE_VISIBLE; + + /* disable configuration buttons */ + m->buttons[10].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + m->buttons[11].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + m->buttons[12].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + + /* update directions */ + m->buttons[2].shift[3] = 0; + m->buttons[3].shift[3] = 0; + m->buttons[4].shift[3] = 0; + m->buttons[5].shift[3] = 0; + m->buttons[6].shift[3] = 0; + m->buttons[7].shift[3] = 0; + m->buttons[8].shift[3] = 0; + m->buttons[9].shift[3] = 0; + + /* update title */ + sprintf(m->title,"Controller Settings"); + } + + break; + } + + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + { + /* remove duplicate assigned inputs */ + for (i=0; iselected-2); i++) + { + if (input.dev[i] != NO_DEVICE) player ++; + } + + if (m->bg_images[7].state & IMAGE_VISIBLE) + { + /* if already displayed, do nothing */ + if (old_player == player) break; + + /* slide out configuration window */ + GUI_DrawMenuFX(m, 20, 1); + } + else + { + /* append configuration window */ + m->bg_images[7].state |= IMAGE_VISIBLE; + + /* enable configuration buttons */ + m->buttons[10].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + m->buttons[11].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + m->buttons[12].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + + /* update directions */ + m->buttons[2].shift[3] = 8; + m->buttons[3].shift[3] = 7; + m->buttons[4].shift[3] = 6; + m->buttons[5].shift[3] = 5; + m->buttons[6].shift[3] = 4; + m->buttons[7].shift[3] = 3; + m->buttons[8].shift[3] = 2; + m->buttons[9].shift[3] = 1; + } + + /* emulated device type */ + type = input.dev[m->selected - 2]; + + /* retrieve current player informations */ + switch (type) + { + case DEVICE_PAD3B: + case DEVICE_PAD6B: + { + items = items_special[0]; + special = &config.input[player].padtype; + break; + } + + case DEVICE_MOUSE: + { + items = items_special[1]; + special = &config.invert_mouse; + break; + } + + case DEVICE_LIGHTGUN: + { + items = items_special[2]; + + if ((input.system[1] == SYSTEM_MENACER) || (input.system[1] == SYSTEM_JUSTIFIER)) + { + /* Menacer & Justifiers affected to devices 4 & 5 */ + special = &config.gun_cursor[m->selected & 1]; + } + else + { + /* Lightphasers affected to devices 0 & 4 */ + special = &config.gun_cursor[m->selected >> 2]; + } + break; + } + + default: + { + items = items_special[3]; + special = NULL; + break; + } + } + + if (special) + { + memcpy(&m->items[10],&items[*special],sizeof(gui_item)); + } + else + { + memcpy(&m->items[10],&items[0],sizeof(gui_item)); + } + + memcpy(&m->items[11],&items_device[config.input[player].device + 1],sizeof(gui_item)); + + /* slide in configuration window */ + m->buttons[10].shift[2] = 10 - m->selected; + m->buttons[11].shift[2] = 11 - m->selected; + m->buttons[12].shift[2] = 12 - m->selected; + m->selected = 10; + GUI_DrawMenuFX(m, 20, 0); + + /* some devices require analog sticks */ + if ((type == DEVICE_XE_A1P) && ((config.input[player].device == -1) || (config.input[player].device == 1))) + { + GUI_WaitPrompt("Warning","One Analog Stick required !"); + } + else if ((type == DEVICE_ACTIVATOR) && ((config.input[player].device != 0) && (config.input[player].device != 3))) + { + GUI_WaitPrompt("Warning","Two Analog Sticks required !"); + } + + /* update title */ + if ((cart.special & HW_J_CART) && (player > 1)) + { + sprintf(m->title,"Controller Settings (Player %d) (J-CART)",player+1); + } + else + { + sprintf(m->title,"Controller Settings (Player %d)",player+1); + } + break; + } + + case 10: /* specific option */ + { + if (special) + { + /* switch option */ + *special ^= 1; + + /* specific case: controller type */ + if (type < 2) + { + /* re-initialize emulated device */ + input_init(); + input_reset(); + + /* update emulated device type */ + type = *special; + } + + /* update menu items */ + memcpy(&m->items[10],&items[*special],sizeof(gui_item)); + } + break; + } + + case 11: /* input controller selection */ + { + /* no input device */ + if (config.input[player].device < 0) + { + /* always try gamecube controllers first */ + config.input[player].device = 0; + config.input[player].port = 0; + } + else + { + /* try next port */ + config.input[player].port ++; + } + + /* autodetect connected gamecube controllers */ + if (config.input[player].device == 0) + { + /* find first connected controller */ + exp = 0; + while ((config.input[player].port < 4) && !exp) + { + VIDEO_WaitVSync (); + exp = PAD_ScanPads() & (1<= 4) + { +#ifdef HW_RVL + /* test wiimote */ + config.input[player].port = 0; + config.input[player].device = 1; +#else + /* no input controller left */ + config.input[player].device = -1; + config.input[player].port = player%4; +#endif + } + } + +#ifdef HW_RVL + /* autodetect connected wiimotes (without nunchuk) */ + if (config.input[player].device == 1) + { + /* test current port */ + exp = 255; + if (config.input[player].port < 4) + { + WPAD_Probe(config.input[player].port,&exp); + } + + /* find first connected controller */ + while ((config.input[player].port < 4) && (exp == 255)) + { + /* try next port */ + config.input[player].port ++; + if (config.input[player].port < 4) + { + exp = 255; + WPAD_Probe(config.input[player].port,&exp); + } + } + + /* no more wiimote */ + if (config.input[player].port >= 4) + { + /* test wiimote+nunchuk */ + config.input[player].port = 0; + config.input[player].device = 2; + } + } + + /* autodetect connected wiimote+nunchuk */ + if (config.input[player].device == 2) + { + /* test current port */ + exp = 255; + if (config.input[player].port < 4) + { + WPAD_Probe(config.input[player].port,&exp); + } + + /* find first connected controller */ + while ((config.input[player].port < 4) && (exp != WPAD_EXP_NUNCHUK)) + { + /* try next port */ + config.input[player].port ++; + if (config.input[player].port < 4) + { + exp = 255; + WPAD_Probe(config.input[player].port,&exp); + } + } + + /* no more wiimote+nunchuk */ + if (config.input[player].port >= 4) + { + /* test classic controllers */ + config.input[player].port = 0; + config.input[player].device = 3; + } + } + + /* autodetect connected classic controllers */ + if (config.input[player].device == 3) + { + /* test current port */ + exp = 255; + if (config.input[player].port < 4) + { + WPAD_Probe(config.input[player].port,&exp); + } + + /* find first connected controller */ + while ((config.input[player].port<4) && (exp != WPAD_EXP_CLASSIC)) + { + /* try next port */ + config.input[player].port ++; + if (config.input[player].port < 4) + { + exp = 255; + WPAD_Probe(config.input[player].port,&exp); + } + } + + if (config.input[player].port >= 4) + { + /* no input controller left */ + config.input[player].device = -1; + config.input[player].port = player%4; + } + } +#endif + + /* update menu items */ + memcpy(&m->items[11],&items_device[config.input[player].device + 1],sizeof(gui_item)); + + break; + } + + case 12: /* Controller Keys Configuration */ + { + if (config.input[player].device >= 0) + { + GUI_MsgBoxOpen("Keys Configuration", "",0); + gx_input_Config(config.input[player].port, config.input[player].device, type); + GUI_MsgBoxClose(); + } + break; + } + } + } + + /* Close Window */ + else if (update < 0) + { + if (m->bg_images[7].state & IMAGE_VISIBLE) + { + /* slide out configuration window */ + GUI_DrawMenuFX(m, 20, 1); + + /* disable configuration window */ + m->bg_images[7].state &= ~IMAGE_VISIBLE; + + /* disable configuration buttons */ + m->buttons[10].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + m->buttons[11].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + m->buttons[12].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + + /* clear directions */ + m->buttons[2].shift[3] = 0; + m->buttons[3].shift[3] = 0; + m->buttons[4].shift[3] = 0; + m->buttons[5].shift[3] = 0; + m->buttons[6].shift[3] = 0; + m->buttons[7].shift[3] = 0; + m->buttons[8].shift[3] = 0; + m->buttons[9].shift[3] = 0; + + /* update selector */ + m->selected -= m->buttons[m->selected].shift[2]; + + /* restore title */ + sprintf(m->title,"Controller Settings"); + + /* stay in menu */ + update = 0; + } + else + { + /* check we have at least one connected input before leaving */ + old_player = player; + player = 0; + for (i=0; ibg_images[7].state &= ~IMAGE_VISIBLE; + + /* disable configuration buttons */ + m->buttons[10].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + m->buttons[11].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + m->buttons[12].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE); + + /* clear directions */ + m->buttons[2].shift[3] = 0; + m->buttons[3].shift[3] = 0; + m->buttons[4].shift[3] = 0; + m->buttons[5].shift[3] = 0; + m->buttons[6].shift[3] = 0; + m->buttons[7].shift[3] = 0; + m->buttons[8].shift[3] = 0; + m->buttons[9].shift[3] = 0; + + /* clear menu items */ + memset(&m->items[0],0,sizeof(gui_item)); + memset(&m->items[1],0,sizeof(gui_item)); + memset(&m->items[10],0,sizeof(gui_item)); + memset(&m->items[11],0,sizeof(gui_item)); + + /* clear player buttons */ + m->buttons[2].data = NULL; + m->buttons[3].data = NULL; + m->buttons[4].data = NULL; + m->buttons[5].data = NULL; + m->buttons[6].data = NULL; + m->buttons[7].data = NULL; + m->buttons[8].data = NULL; + m->buttons[9].data = NULL; + + /* delete menu */ + GUI_DeleteMenu(m); + + /* delete custom buttons */ + gxTextureClose(&button_player_data.texture[0]); + gxTextureClose(&button_player_data.texture[1]); + gxTextureClose(&button_player_none_data.texture[0]); + + /* delete custom images */ + for (i=0; i<13; i++) + { + gxTextureClose(&items_sys[0][i].texture); + } + gxTextureClose(&items_special[0][0].texture); + gxTextureClose(&items_special[0][1].texture); + gxTextureClose(&items_special[1][0].texture); + gxTextureClose(&items_special[1][1].texture); + gxTextureClose(&items_device[1].texture); +#ifdef HW_RVL + gxTextureClose(&items_device[2].texture); + gxTextureClose(&items_device[3].texture); + gxTextureClose(&items_device[4].texture); +#endif +} + +/**************************************************************************** + * Main Option menu + * + ****************************************************************************/ +static void optionmenu(void) +{ + int ret, quit = 0; + gui_menu *m = &menu_options; + + GUI_InitMenu(m); + GUI_DrawMenuFX(m,30,0); + + while (quit == 0) + { + ret = GUI_RunMenu(m); + + switch (ret) + { + case 0: + GUI_DeleteMenu(m); + systemmenu(); + GUI_InitMenu(m); + break; + case 1: + GUI_DeleteMenu(m); + videomenu(); + GUI_InitMenu(m); + break; + case 2: + GUI_DeleteMenu(m); + soundmenu(); + GUI_InitMenu(m); + break; + case 3: + GUI_DeleteMenu(m); + ctrlmenu(); + GUI_InitMenu(m); + break; + case 4: + GUI_DeleteMenu(m); + prefmenu(); + GUI_InitMenu(m); + break; + case -1: + quit = 1; + break; + } + } + + config_save(); + GUI_DrawMenuFX(m,30,1); + GUI_DeleteMenu(m); +} + +/**************************************************************************** +* Save Manager menu +* +****************************************************************************/ +static t_slot slots[5]; +static void savemenu_cb(void) +{ + int i; + char msg[16]; + gx_texture *star = gxTextureOpenPNG(Star_full_png,0); + + if (sram.on) + { + FONT_write("Backup Memory",16,buttons_saves[0].x+16,buttons_saves[0].y+(buttons_saves[0].h-16)/2+16,buttons_saves[0].x+buttons_saves[0].w,(GXColor)DARK_GREY); + if (slots[0].valid) + { + sprintf(msg,"%d/%02d/%02d",slots[0].day,slots[0].month,slots[0].year); + FONT_alignRight(msg,12,buttons_saves[0].x+buttons_saves[0].w-16,buttons_saves[0].y+(buttons_saves[0].h-28)/2+12,(GXColor)DARK_GREY); + sprintf(msg,"%02d:%02d",slots[0].hour,slots[0].min); + FONT_alignRight(msg,12,buttons_saves[0].x+buttons_saves[0].w-16,buttons_saves[0].y+(buttons_saves[0].h-28)/2+28,(GXColor)DARK_GREY); + } + + if (sram.crc != crc32(0, &sram.sram[0], 0x10000)) + gxDrawTexture(star,22,buttons_saves[0].y+(buttons_saves[0].h-star->height)/2,star->width,star->height,255); + } + else + { + FONT_writeCenter("Backup Memory disabled",16,buttons_saves[0].x,buttons_saves[0].x+buttons_saves[0].w,buttons_saves[0].y+(buttons_saves[0].h-16)/2+16,(GXColor)DARK_GREY); + } + + for (i=1; i<5; i++) + { + if (slots[i].valid) + { + sprintf(msg,"Slot %d",i); + FONT_write(msg,16,buttons_saves[i].x+16,buttons_saves[i].y+(buttons_saves[i].h-16)/2+16,buttons_saves[i].x+buttons_saves[i].w,(GXColor)DARK_GREY); + sprintf(msg,"%d/%02d/%02d",slots[i].day,slots[i].month,slots[i].year); + FONT_alignRight(msg,12,buttons_saves[i].x+buttons_saves[i].w-16,buttons_saves[i].y+(buttons_saves[i].h-28)/2+12,(GXColor)DARK_GREY); + sprintf(msg,"%02d:%02d",slots[i].hour,slots[i].min); + FONT_alignRight(msg,12,buttons_saves[i].x+buttons_saves[i].w-16,buttons_saves[i].y+(buttons_saves[i].h-28)/2+28,(GXColor)DARK_GREY); + } + else + { + FONT_write("Empty Slot",16,buttons_saves[i].x+16,buttons_saves[i].y+(buttons_saves[i].h-16)/2+16,buttons_saves[i].x+buttons_saves[i].h,(GXColor)DARK_GREY); + } + + if (i == config.s_default) + gxDrawTexture(star,22,buttons_saves[i].y+(buttons_saves[i].h-star->height)/2,star->width,star->height,255); + } + gxTextureClose(&star); +} + +static int savemenu(void) +{ + int i, update = 0; + int ret = 0; + int slot = -1; + char filename[MAXPATHLEN]; + gui_menu *m = &menu_saves; + FILE *snap; + + GUI_InitMenu(m); + GUI_DrawMenuFX(m,30,0); + + m->bg_images[3].state &= ~IMAGE_SLIDE_TOP; + m->bg_images[4].state &= ~IMAGE_SLIDE_BOTTOM; + m->bg_images[5].state &= ~IMAGE_SLIDE_TOP; + + /* detect existing files */ + for (i=0; i<5; i++) + slot_autodetect(i, config.s_device, &slots[i]); + + /* SRAM disabled */ + if (sram.on) + { + m->buttons[0].state |= BUTTON_ACTIVE; + m->buttons[1].shift[0] = 1; + } + else + { + m->buttons[0].state &= ~BUTTON_ACTIVE; + m->buttons[1].shift[0] = 0; + if (m->selected == 0) + m->selected = 1; + } + + while (update != -1) + { + /* slot selection */ + if ((m->selected < 5) && (slot != m->selected)) + { + /* update slot */ + slot = m->selected; + + /* delete previous texture if any */ + gxTextureClose(&bg_saves[0].texture); + bg_saves[0].state &= ~IMAGE_VISIBLE; + bg_saves[1].state |= IMAGE_VISIBLE; + + /* state slot */ + if (!config.s_device && slot && slots[slot].valid) + { + /* open screenshot file */ + sprintf (filename, "%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1); + snap = fopen(filename, "rb"); + if (snap) + { + /* load texture from file */ + bg_saves[0].texture = gxTextureOpenPNG(0,snap); + if (bg_saves[0].texture) + { + /* set menu background */ + bg_saves[0].w = bg_saves[0].texture->width * 2; + if (config.aspect & 2) bg_saves[0].w = (bg_saves[0].w * 3) / 4; + bg_saves[0].h = bg_saves[0].texture->height * 2; + bg_saves[0].x = (vmode->fbWidth - bg_saves[0].w) / 2; + bg_saves[0].y = (vmode->efbHeight - bg_saves[0].h) / 2; + bg_saves[0].state |= IMAGE_VISIBLE; + bg_saves[1].state &= ~IMAGE_VISIBLE; + } + fclose(snap); + } + } + } + + /* draw menu */ + GUI_DrawMenu(m); + + /* update menu */ + update = GUI_UpdateMenu(m); + + if (update > 0) + { + switch (m->selected) + { + case 0: + case 1: + case 2: + case 3: + case 4: /* Slot selection */ + { + /* enable right window */ + m->bg_images[7].state |= IMAGE_VISIBLE; + m->buttons[5].state |= BUTTON_VISIBLE; + m->buttons[6].state |= BUTTON_VISIBLE; + m->buttons[7].state |= BUTTON_VISIBLE; + m->buttons[8].state |= BUTTON_VISIBLE; + + /* only enable valid options */ + if (slots[slot].valid) + { + m->buttons[5].state |= BUTTON_ACTIVE; + m->buttons[7].state |= BUTTON_ACTIVE; + m->buttons[6].shift[0] = 1; + m->buttons[6].shift[1] = 1; + m->buttons[8].shift[0] = 1; + m->selected = 5; + } + else + { + m->buttons[5].state &= ~BUTTON_ACTIVE; + m->buttons[7].state &= ~BUTTON_ACTIVE; + m->buttons[6].shift[0] = 0; + m->buttons[6].shift[1] = 2; + m->buttons[8].shift[0] = (slot > 0) ? 2 : 0; + m->selected = 8; + } + + /* state slot 'only' button */ + if (slot > 0) + { + m->buttons[6].state |= BUTTON_ACTIVE; + m->buttons[5].shift[1] = 1; + m->buttons[7].shift[0] = 1; + } + else + { + m->buttons[6].state &= ~BUTTON_ACTIVE; + m->buttons[5].shift[1] = 2; + m->buttons[7].shift[0] = 2; + } + + /* disable left buttons */ + m->buttons[0].state &= ~BUTTON_ACTIVE; + m->buttons[1].state &= ~BUTTON_ACTIVE; + m->buttons[2].state &= ~BUTTON_ACTIVE; + m->buttons[3].state &= ~BUTTON_ACTIVE; + m->buttons[4].state &= ~BUTTON_ACTIVE; + + /* keep current selection highlighted */ + m->buttons[slot].state |= BUTTON_SELECTED; + + /* slide in window */ + GUI_DrawMenuFX(m, 20, 0); + + break; + } + + case 5: /* load file */ + { + if (slots[slot].valid) + { + ret = slot_load(slot,config.s_device); + + /* force exit */ + if (ret > 0) + { + GUI_DrawMenuFX(m, 20, 1); + m->buttons[slot].state &= ~BUTTON_SELECTED; + m->bg_images[7].state &= ~IMAGE_VISIBLE; + if (sram.on) + m->buttons[0].state |= BUTTON_ACTIVE; + m->buttons[1].state |= BUTTON_ACTIVE; + m->buttons[2].state |= BUTTON_ACTIVE; + m->buttons[3].state |= BUTTON_ACTIVE; + m->buttons[4].state |= BUTTON_ACTIVE; + m->buttons[5].state &= ~BUTTON_VISIBLE; + m->buttons[6].state &= ~BUTTON_VISIBLE; + m->buttons[7].state &= ~BUTTON_VISIBLE; + m->buttons[8].state &= ~BUTTON_VISIBLE; + m->selected = slot; + update = -1; + } + } + break; + } + + case 6: /* set default slot */ + { + config.s_default = slot; + config_save(); + break; + } + + case 7: /* delete file */ + { + if (slots[slot].valid) + { + if (slot_delete(slot,config.s_device) >= 0) + { + /* hide screenshot */ + gxTextureClose(&bg_saves[0].texture); + bg_saves[0].state &= ~IMAGE_VISIBLE; + slots[slot].valid = 0; + update = -1; + } + } + break; + } + + case 8: /* save file */ + { + ret = slot_save(slot,config.s_device); + + /* force exit */ + if (ret > 0) + { + GUI_DrawMenuFX(m, 20, 1); + m->buttons[slot].state &= ~BUTTON_SELECTED; + m->bg_images[7].state &= ~IMAGE_VISIBLE; + if (sram.on) + m->buttons[0].state |= BUTTON_ACTIVE; + m->buttons[1].state |= BUTTON_ACTIVE; + m->buttons[2].state |= BUTTON_ACTIVE; + m->buttons[3].state |= BUTTON_ACTIVE; + m->buttons[4].state |= BUTTON_ACTIVE; + m->buttons[5].state &= ~BUTTON_VISIBLE; + m->buttons[6].state &= ~BUTTON_VISIBLE; + m->buttons[7].state &= ~BUTTON_VISIBLE; + m->buttons[8].state &= ~BUTTON_VISIBLE; + m->selected = slot; + update = -1; + } + break; + } + + default: + break; + } + } + + if (update < 0) + { + /* close right window */ + if (m->bg_images[7].state & IMAGE_VISIBLE) + { + /* slide out window */ + GUI_DrawMenuFX(m, 20, 1); + + /* clear current selection */ + m->buttons[slot].state &= ~BUTTON_SELECTED; + + /* enable left buttons */ + if (sram.on) + m->buttons[0].state |= BUTTON_ACTIVE; + m->buttons[1].state |= BUTTON_ACTIVE; + m->buttons[2].state |= BUTTON_ACTIVE; + m->buttons[3].state |= BUTTON_ACTIVE; + m->buttons[4].state |= BUTTON_ACTIVE; + + /* disable right window */ + m->bg_images[7].state &= ~IMAGE_VISIBLE; + m->buttons[5].state &= ~BUTTON_VISIBLE; + m->buttons[6].state &= ~BUTTON_VISIBLE; + m->buttons[7].state &= ~BUTTON_VISIBLE; + m->buttons[8].state &= ~BUTTON_VISIBLE; + + /* stay in menu */ + m->selected = slot; + update = 0; + } + } + } + + /* leave menu */ + m->bg_images[3].state |= IMAGE_SLIDE_TOP; + m->bg_images[4].state |= IMAGE_SLIDE_BOTTOM; + m->bg_images[5].state |= IMAGE_SLIDE_TOP; + GUI_DrawMenuFX(m,30,1); + GUI_DeleteMenu(m); + return ret; +} + +/**************************************************************************** + * Load Game menu + * + ****************************************************************************/ +static int loadgamemenu () +{ + int ret, filetype; + gui_menu *m = &menu_load; + GUI_InitMenu(m); + GUI_DrawMenuFX(m,30,0); + + while (1) + { + ret = GUI_RunMenu(m); + + switch (ret) + { + /*** Button B ***/ + case -1: + GUI_DrawMenuFX(m,30,1); + GUI_DeleteMenu(m); + return 0; + + /*** Load from selected device */ + default: + { + /* ROM File type */ + filetype = ret - 1; + + /* Try to open current directory */ + if (ret > 0) + { + ret = OpenDirectory(config.l_device, filetype); + } + else + { + ret = OpenDirectory(TYPE_RECENT, filetype); + } + + if (ret) + { + GUI_DeleteMenu(m); + if (FileSelector(filetype)) + { + /* directly jump to game */ + return 1; + } + GUI_InitMenu(m); + } + break; + } + } + } + + return 0; +} + +/*************************************************************************** + * Show rom info screen + ***************************************************************************/ +static void showrominfo (void) +{ + char items[15][64]; + char msg[32]; + + /* fill ROM infos */ + sprintf (items[0], "Console Type: %s", rominfo.consoletype); + sprintf (items[1], "Copyright: %s", rominfo.copyright); + sprintf (items[2], "Company Name: %s", get_company()); + sprintf (items[3], "Domestic Name:"); + sprintf (items[4], "%s",rominfo.domestic); + sprintf (items[5], "International Name:"); + sprintf (items[6], "%s",rominfo.international); + sprintf (items[7], "Type: %s (%s)",rominfo.ROMType, strcmp(rominfo.ROMType, "AI") ? "Game" : "Educational"); + sprintf (items[8], "Product ID: %s", rominfo.product); + sprintf (items[9], "Checksum: %04x (%04x) (%s)", rominfo.checksum, rominfo.realchecksum, + (rominfo.checksum == rominfo.realchecksum) ? "GOOD" : "BAD"); + + sprintf (items[10], "Supports: "); + if (rominfo.peripherals & (1 << 1)) + { + strcat(items[10],get_peripheral(1)); + strcat(items[10],", "); + } + else if (rominfo.peripherals & (1 << 0)) + { + strcat(items[10],get_peripheral(0)); + strcat(items[10],", "); + } + if (rominfo.peripherals & (1 << 7)) + { + strcat(items[10],get_peripheral(7)); + strcat(items[10],", "); + } + if (rominfo.peripherals & (1 << 8)) + { + strcat(items[10],get_peripheral(8)); + strcat(items[10],", "); + } + if (rominfo.peripherals & (1 << 11)) + { + strcat(items[10],get_peripheral(11)); + strcat(items[10],", "); + } + if (rominfo.peripherals & (1 << 13)) + { + strcat(items[10],get_peripheral(13)); + strcat(items[10],", "); + } + if (strlen(items[10]) > 10) + items[10][strlen(items[10]) - 2] = 0; + + sprintf (items[11], "ROM end: $%06X", rominfo.romend); + + if (sram.custom) + sprintf (items[12], "Serial EEPROM"); + else if (sram.detected) + sprintf (items[12], "SRAM Start: $%06X", sram.start); + else + sprintf (items[12], "No Backup Memory specified"); + + if (sram.custom == 1) + sprintf (items[13], "Type: I2C (24Cxx)"); + else if (sram.custom == 2) + sprintf (items[13], "Type: SPI (25x512/95x512)"); + else if (sram.custom == 3) + sprintf (items[13], "Type: I2C (93C46)"); + else if (sram.detected) + sprintf (items[13], "SRAM End: $%06X", sram.end); + else if (sram.on) + sprintf (items[13], "SRAM enabled by default"); + else + sprintf (items[13], "SRAM disabled by default"); + + if (region_code == REGION_USA) + sprintf (items[14], "Region Code: %s (USA)", rominfo.country); + else if (region_code == REGION_EUROPE) + sprintf (items[14], "Region Code: %s (EUR)", rominfo.country); + else if (region_code == REGION_JAPAN_NTSC) + sprintf (items[14], "Region Code: %s (JPN)", rominfo.country); + else if (region_code == REGION_JAPAN_PAL) + sprintf (items[14], "Region Code: %s (JPN-PAL)", rominfo.country); + +#ifdef USE_BENCHMARK + /* ROM benchmark */ + if (!config.ntsc) + { + int frames = 0; + u64 start = gettime(); + do + { + system_frame(0); + audio_update(); + } + while (++frames < 300); + u64 end = gettime(); + sprintf(msg,"ROM Header Info (%d fps)", (300 * 1000000) / diff_usec(start,end)); + } + else +#endif + { + strcpy(msg,"ROM Header Info"); + } + + GUI_TextWindow(&menu_main, msg, items, 15, 15); +} + +/*************************************************************************** + * Show credits + ***************************************************************************/ +static void showcredits(void) +{ + int offset = 0; + + gx_texture *texture = gxTextureOpenPNG(Bg_credits_png,0); + s16 p = 0; + + while (!p) + { + gxClearScreen ((GXColor)BLACK); + if (texture) + gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255); + + FONT_writeCenter("Genesis Plus Core", 24, 0, 640, 480 - offset, (GXColor)LIGHT_BLUE); + FONT_writeCenter("improved emulation code, fixes & extra features by Eke-Eke", 18, 0, 640, 516 - offset, (GXColor)WHITE); + FONT_writeCenter("original 1.3 version by Charles MacDonald", 18, 0, 640, 534 - offset, (GXColor)WHITE); + FONT_writeCenter("original Z80 core by Juergen Buchmueller", 18, 0, 640, 552 - offset, (GXColor)WHITE); + FONT_writeCenter("original 68k core (Musashi) by Karl Stenerud", 18, 0, 640, 570 - offset, (GXColor)WHITE); + FONT_writeCenter("original YM2612/2413 cores by Jarek Burczynski, Tatsuyuki Satoh", 18, 0, 640, 588 - offset, (GXColor)WHITE); + FONT_writeCenter("original SN76489 core by Maxim", 18, 0, 640, 606 - offset, (GXColor)WHITE); + FONT_writeCenter("SVP core by Gravydas Ignotas (Notaz)", 18, 0, 640, 624 - offset, (GXColor)WHITE); + FONT_writeCenter("Blip Buffer Library & NTSC Video Filter by Shay Green (Blargg)", 18, 0, 640, 642 - offset, (GXColor)WHITE); + FONT_writeCenter("3-Band EQ implementation by Neil C", 18, 0, 640, 660 - offset, (GXColor)WHITE); + + FONT_writeCenter("Special thanks to ...", 20, 0, 640, 700 - offset, (GXColor)LIGHT_GREEN); + FONT_writeCenter("Nemesis, Tasco Deluxe, Bart Trzynadlowski, Jorge Cwik, Haze,", 18, 0, 640, 736 - offset, (GXColor)WHITE); + FONT_writeCenter("Stef Dallongeville, Notaz, AamirM, Steve Snake, Charles MacDonald", 18, 0, 640, 754 - offset, (GXColor)WHITE); + FONT_writeCenter("Spritesmind & SMS Power forums members for their technical help", 18, 0, 640, 772 - offset, (GXColor)WHITE); + + FONT_writeCenter("Gamecube & Wii port", 24, 0, 640, 830 - offset, (GXColor)LIGHT_BLUE); + FONT_writeCenter("porting code, GUI engine & design by Eke-Eke", 18, 0, 640, 866 - offset, (GXColor)WHITE); + FONT_writeCenter("original Gamecube port by Softdev, Honkeykong & Markcube", 18, 0, 640, 884 - offset, (GXColor)WHITE); + FONT_writeCenter("original icons, logo & button design by Low Lines", 18, 0, 640, 906 - offset, (GXColor)WHITE); + FONT_writeCenter("credit illustration by Orioto (Deviant Art)", 18, 0, 640, 924 - offset, (GXColor)WHITE); + FONT_writeCenter("memory card icon design by Brakken", 18, 0, 640, 942 - offset, (GXColor)WHITE); + FONT_writeCenter("libogc by Shagkur & various other contibutors", 18, 0, 640, 960 - offset, (GXColor)WHITE); + FONT_writeCenter("libfat by Chism", 18, 0, 640, 978 - offset, (GXColor)WHITE); + FONT_writeCenter("wiiuse by Michael Laforest (Para)", 18, 0, 640, 996 - offset, (GXColor)WHITE); + FONT_writeCenter("asndlib & OGG player by Francisco Muñoz (Hermes)", 18, 0, 640, 1014 - offset, (GXColor)WHITE); + FONT_writeCenter("zlib, libpng & libtremor by their respective authors", 18, 0, 640, 1032 - offset, (GXColor)WHITE); + FONT_writeCenter("devkitPPC by Wintermute", 18, 0, 640, 1050 - offset, (GXColor)WHITE); + + FONT_writeCenter("Special thanks to ...", 20, 0, 640, 1090 - offset, (GXColor)LIGHT_GREEN); + FONT_writeCenter("Softdev, Tmbinc, Costis, Emukiddid, Team Twiizer", 18, 0, 640, 1126 - offset, (GXColor)WHITE); + FONT_writeCenter("Brakken & former Tehskeen members for their support", 18, 0, 640, 1144 - offset, (GXColor)WHITE); + FONT_writeCenter("Anca, my wife, for her patience & various ideas", 18, 0, 640, 1162 - offset, (GXColor)WHITE); + + gxSetScreen(); + p = m_input.keys; + gxSetScreen(); + p |= m_input.keys; + offset ++; + if (offset > 1144) + offset = 0; + } + + gxTextureClose(&texture); +} + +static void exitmenu(void) +{ + char *items[3] = + { + "View Credits", +#ifdef HW_RVL + "Exit to System Menu", +#else + "Reset System", +#endif + "Return to Loader", + }; + + /* check if loader stub exists */ + int maxitems = reload ? 3 : 2; + + /* display option window */ + switch (GUI_OptionWindow(&menu_main, osd_version, items, maxitems)) + { + case 0: /* credits */ + GUI_DeleteMenu(&menu_main); + showcredits(); + GUI_InitMenu(&menu_main); + break; + + case 1: /* reset */ +#ifdef HW_RVL + gxTextureClose(&w_pointer); +#endif + GUI_DeleteMenu(&menu_main); + GUI_FadeOut(); + shutdown(); +#ifdef HW_RVL + SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); +#else + SYS_ResetSystem(SYS_HOTRESET,0,0); +#endif + break; + + case 2: /* exit to loader */ +#ifdef HW_RVL + gxTextureClose(&w_pointer); +#endif + GUI_DeleteMenu(&menu_main); + GUI_FadeOut(); + shutdown(); + SYS_ResetSystem(SYS_SHUTDOWN,0,0); + __lwp_thread_stopmultitasking(*reload); + break; + + default: + break; + } +} + +/**************************************************************************** + * Main Menu + * + ****************************************************************************/ + +static void mainmenu_cb(void) +{ + char temp[4]; + gui_menu *m = &menu_main; + int status = areplay_get_status(); + + /* Action Replay Switch current status */ + if (status == AR_SWITCH_TRAINER) strcpy(temp,"TM"); + else if (status == AR_SWITCH_ON) strcpy(temp,"ON"); + else strcpy(temp,"OFF"); + + /* Display informations */ + if (m->selected == 6) + { + FONT_writeCenter("Action\nReplay", 14, m->items[6].x, m->items[6].x + 54, m->items[6].y + (m->items[6].h - 28)/2 + 14, (GXColor)DARK_GREY); + FONT_writeCenter(temp, 11, m->items[6].x + 56 + 3, m->items[6].x + 78 + 2, m->items[6].y + (m->items[6].h - 11)/2 + 11, (GXColor)DARK_GREY); + } + else + { + FONT_writeCenter("Action\nReplay", 12, m->items[6].x + 4, m->items[6].x + 54, m->items[6].y + (m->items[6].h - 24)/2 + 12, (GXColor)DARK_GREY); + FONT_writeCenter(temp, 10, m->items[6].x + 56, m->items[6].x + 78, m->items[6].y + (m->items[6].h - 10)/2 + 10, (GXColor)DARK_GREY); + } +} + +void mainmenu(void) +{ + char filename[MAXPATHLEN]; + int status, quit = 0; + + /* Autosave Backup RAM */ + slot_autosave(0, config.s_device); + +#ifdef HW_RVL + /* Detect shutdown request */ + if (Shutdown) + { + GUI_FadeOut(); + shutdown(); + if (reload) + { + /* exit to loader if requested */ + SYS_ResetSystem(SYS_SHUTDOWN,0,0); + __lwp_thread_stopmultitasking(*reload); + } + else + { + /* shutdown system by default */ + SYS_ResetSystem(SYS_POWEROFF, 0, 0); + } + } + + /* Wiimote pointer */ + w_pointer = gxTextureOpenPNG(generic_point_png,0); +#endif + + gui_menu *m = &menu_main; + + /* Update main menu */ + if (!m->screenshot) + { + if (config.bg_overlay) + { + bg_main[1].state |= IMAGE_VISIBLE; + bg_misc[1].state |= IMAGE_VISIBLE; + bg_ctrls[1].state |= IMAGE_VISIBLE; + bg_list[1].state |= IMAGE_VISIBLE; + bg_saves[2].state |= IMAGE_VISIBLE; + } + else + { + bg_main[1].state &= ~IMAGE_VISIBLE; + bg_misc[1].state &= ~IMAGE_VISIBLE; + bg_ctrls[1].state &= ~IMAGE_VISIBLE; + bg_list[1].state &= ~IMAGE_VISIBLE; + bg_saves[2].state &= ~IMAGE_VISIBLE; + } + + if (system_hw) + { + m->screenshot = 128; + m->bg_images[0].state &= ~IMAGE_VISIBLE; + m->items[0].y -= 90; + m->items[1].y -= 90; + m->items[2].y -= 90; + m->buttons[0].y -= 90; + m->buttons[1].y -= 90; + m->buttons[2].y -= 90; + m->buttons[0].shift[1] = 3; + m->buttons[1].shift[1] = 3; + m->buttons[2].shift[1] = 3; + m->buttons[3].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + m->buttons[4].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + m->buttons[5].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + m->buttons[7].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + m->buttons[8].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + m->buttons[9].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + if (areplay_get_status() >= 0) + { + menu_main.buttons[6].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + menu_main.items[6].data = Button_sm_grey_png; + menu_main.cb = mainmenu_cb; + menu_main.buttons[3].shift[1] = 3; + menu_main.buttons[7].shift[0] = 1; + menu_main.buttons[8].shift[2] = 2; + } + } + } + + GUI_InitMenu(m); + GUI_DrawMenuFX(m,10,0); + + while (quit == 0) + { + switch (GUI_RunMenu(m)) + { + /*** Load Game Menu ***/ + case 0: + { + GUI_DrawMenuFX(m,30,1); + GUI_DeleteMenu(m); + + if (loadgamemenu()) + { + /* restart emulation */ + reloadrom(); + + /* check current controller configuration */ + if (!gx_input_FindDevices()) + { + GUI_InitMenu(m); + GUI_DrawMenuFX(m,30,0); + GUI_WaitPrompt("Error","Invalid Controllers Settings"); + break; + } + + /* exit to game and reinitialize emulation */ + gxClearScreen((GXColor)BLACK); + gxSetScreen(); + quit = 1; + break; + } + + GUI_InitMenu(m); + GUI_DrawMenuFX(m,30,0); + break; + } + + /*** Options Menu */ + case 1: + { + GUI_DrawMenuFX(m,30,1); + GUI_DeleteMenu(m); + optionmenu(); + GUI_InitMenu(m); + GUI_DrawMenuFX(m,30,0); + break; + } + + /*** Exit Menu ***/ + case 2: + { + exitmenu(); + break; + } + + /*** Save Manager ***/ + case 3: + { + GUI_DrawMenuFX(m,30,1); + GUI_DeleteMenu(m); + + if (savemenu()) + { + /* check current controller configuration */ + if (!gx_input_FindDevices()) + { + GUI_InitMenu(m); + GUI_DrawMenuFX(m,30,0); + GUI_WaitPrompt("Error","Invalid Controllers Settings"); + break; + } + + /* exit to game */ + quit = 1; + break; + } + + GUI_InitMenu(m); + GUI_DrawMenuFX(m,30,0); + break; + } + + /*** Soft / Hard reset ***/ + case 4: + { + /* check current controller configuration */ + if (!gx_input_FindDevices()) + { + GUI_WaitPrompt("Error","Invalid Controllers Settings"); + break; + } + + /* reinitialize emulation */ + GUI_DrawMenuFX(m,10,1); + GUI_DeleteMenu(m); + gxClearScreen((GXColor)BLACK); + gxSetScreen(); + + if (system_hw & SYSTEM_MD) + { + /* Soft Reset */ + gen_reset(0); + } + else if (system_hw == SYSTEM_SMS) + { + /* assert RESET input (Master System model 1 only) */ + io_reg[0x0D] &= ~IO_RESET_HI; + } + else + { + /* Hard Reset */ + system_init(); + system_reset(); + + /* restore SRAM */ + slot_autoload(0,config.s_device); + } + + /* exit to game */ + quit = 1; + break; + } + + /*** Cheats menu ***/ + case 5: + { + GUI_DrawMenuFX(m,30,1); + GUI_DeleteMenu(m); + CheatMenu(); + GUI_InitMenu(m); + GUI_DrawMenuFX(m,30,0); + break; + } + + /*** Action Replay switch ***/ + case 6: + { + status = (areplay_get_status() + 1) % (AR_SWITCH_TRAINER + 1); + areplay_set_status(status); + status = areplay_get_status(); + GUI_DeleteMenu(m); + if (status == AR_SWITCH_TRAINER) m->items[6].data = Button_sm_blue_png; + else if (status == AR_SWITCH_ON) m->items[6].data = Button_sm_yellow_png; + else m->items[6].data = Button_sm_grey_png; + GUI_InitMenu(m); + break; + } + + /*** Return to Game ***/ + case 7: + case -1: + { + if (system_hw) + { + /* check current controller configuration */ + if (!gx_input_FindDevices()) + { + GUI_WaitPrompt("Error","Invalid Controllers Settings"); + break; + } + + /* exit to game */ + GUI_DrawMenuFX(m,10,1); + GUI_DeleteMenu(m); + quit = 1; + } + break; + } + + /*** Game Capture ***/ + case 8: + { + /* PNG filename */ + sprintf(filename,"%s/snaps/%s.png", DEFAULT_PATH, rom_filename); + + /* Save file and return */ + gxSaveScreenshot(filename); + break; + } + + /*** ROM information screen ***/ + case 9: + { + showrominfo(); + break; + } + } + } + + /*** Remove any still held buttons ***/ + while (PAD_ButtonsHeld(0)) + { + VIDEO_WaitVSync(); + PAD_ScanPads(); + } +#ifdef HW_RVL + while (WPAD_ButtonsHeld(0)) + { + VIDEO_WaitVSync(); + WPAD_ScanPads(); + } + gxTextureClose(&w_pointer); + + /* USB Mouse support */ + if ((input.system[0] == SYSTEM_MOUSE) || (input.system[1] == SYSTEM_MOUSE)) + { + MOUSE_Init(); + } + else + { + MOUSE_Deinit(); + } +#endif +} diff --git a/genplus-gx/gx/gui/menu.h b/genplus-gx/gx/gui/menu.h new file mode 100644 index 0000000000..e10c2255a3 --- /dev/null +++ b/genplus-gx/gx/gui/menu.h @@ -0,0 +1,46 @@ +/**************************************************************************** + * menu.c + * + * Genesis Plus GX menus + * + * Copyright Eke-Eke (2009-2013) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _MENU_H +#define _MENU_H + +extern void mainmenu(void); +extern void (*reload)(void); + +#endif diff --git a/genplus-gx/gx/gui/saveicon.h b/genplus-gx/gx/gui/saveicon.h new file mode 100644 index 0000000000..a0ae7547da --- /dev/null +++ b/genplus-gx/gx/gui/saveicon.h @@ -0,0 +1,136 @@ +/*********************************************************** + * Genesis Plus Save Icon + * Made by Brakken (http://www.tehskeen.com) + * + ************************************************************/ +unsigned short icon[1024] = { + + 0xFFFF, 0xFFFF, 0xFBDE, 0xFBDE, 0xFBDE, 0xFBDE, 0xFBDE, 0xEB5A, + 0xFBDE, 0xFBDE, 0xFBDE, 0xBDCD, 0xFBDE, 0xF7BD, 0xF7BD, 0xAD49, + 0xEB59, 0xB9AD, 0xC1EF, 0xC1EF, 0x9062, 0x8000, 0x8C41, 0x8C41, + 0x8000, 0x9CE6, 0xA0E6, 0xA507, 0x8400, 0x9CC5, 0xA0E6, 0xA0E6, + 0xC1EF, 0xC1EF, 0xC1EF, 0xC1EF, 0x8000, 0x8000, 0x8000, 0x8000, + 0x9083, 0x8C63, 0x8C63, 0x9484, 0x8C63, 0x9083, 0x9484, 0x94A4, + 0xC1EF, 0xC20F, 0xC20F, 0xBDCE, 0x8000, 0x8000, 0x8000, 0x8000, + 0x9083, 0x8821, 0x8842, 0x8842, 0x8842, 0xA107, 0xB58C, 0xAD6B, + 0xA529, 0x94A4, 0x9083, 0x94A4, 0x8000, 0x8000, 0x8400, 0x8400, + 0x8842, 0x8842, 0x8842, 0x8821, 0xB18B, 0xA949, 0xA108, 0xA107, + 0xA528, 0xB9AD, 0xC630, 0xCE51, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8821, 0x8821, 0x8821, 0x8400, 0xA108, 0xA529, 0xA108, 0xA529, + 0xCA30, 0xC630, 0xCA30, 0xFBDE, 0x8000, 0x8000, 0x8000, 0xAD27, + 0x8400, 0x9083, 0x8863, 0x8400, 0x9CE6, 0x8842, 0x8C63, 0x8C20, + 0xFBDE, 0xFBDE, 0xFFFF, 0xFFFF, 0xFBDE, 0xFBDE, 0xFBDE, 0xFBDE, + 0xDA92, 0xFBDE, 0xFBDE, 0xFBDE, 0xC1AB, 0xF7BD, 0xFBDE, 0xFBDE, + 0xF7BD, 0xF7BD, 0xF7BD, 0xA0E6, 0xF7BD, 0xF7BD, 0xF39C, 0x9484, + 0xF39C, 0xF39C, 0xDEF7, 0x8C41, 0xF39C, 0xEF7B, 0xD272, 0x8400, + 0x8C42, 0x9CE6, 0xA507, 0xA0E6, 0x8C63, 0x9CC5, 0xA107, 0x9CE6, + 0x9484, 0x98A5, 0x9CE6, 0x98C5, 0x9CC5, 0x98C5, 0xA0E7, 0x98C5, + 0x8C42, 0x9083, 0x94A5, 0x9083, 0x8C42, 0x9083, 0x9084, 0x8C62, + 0x8C62, 0x9083, 0x9084, 0x8C62, 0x8C63, 0x9083, 0x94A4, 0x8C63, + 0x8842, 0x9CC6, 0xA107, 0xA0E7, 0x8842, 0x8842, 0xA108, 0xA54A, + 0x8842, 0x8C63, 0xB5AD, 0xB5AD, 0x8C63, 0x8C62, 0x8842, 0x8C63, + 0x98C5, 0xA528, 0xB5AC, 0xB5AC, 0xA52A, 0xBDEF, 0xC631, 0xCA52, + 0xB9CE, 0xB9CE, 0xA94A, 0xAD6B, 0x8C63, 0x8821, 0x8821, 0x8821, + 0xA529, 0x98C5, 0x98C5, 0xA0E6, 0xC210, 0xA529, 0xA529, 0xA529, + 0xB5AD, 0xB5CD, 0xB5AD, 0xBDEF, 0x8400, 0x8821, 0x8C62, 0x8821, + 0xA0E7, 0x8842, 0x8842, 0x8C41, 0x9083, 0x8842, 0x8842, 0x8842, + 0x94A5, 0x8842, 0x8C62, 0x8C62, 0x8C42, 0x9083, 0x8C62, 0x8C62, + 0xB548, 0xF7BD, 0xF7BD, 0xF7BD, 0xA4C4, 0xF7BD, 0xF7BD, 0xF7BD, + 0x9461, 0xDED5, 0xF39C, 0xF39C, 0x8C20, 0xD271, 0xF39C, 0xF39C, + 0xEF7B, 0xEF7B, 0xC610, 0x8400, 0xEF7B, 0xEB5A, 0xB9AC, 0x8000, + 0xEB5A, 0xEB5A, 0xA528, 0x9CC5, 0xE739, 0xE739, 0x9CC6, 0x98A5, + 0x98C5, 0x98C5, 0xA0E6, 0x94A4, 0x94A4, 0x98C5, 0x94A5, 0x9484, + 0xA528, 0x98C5, 0x9CE6, 0xA0E7, 0x9CE6, 0xA4E6, 0x98A4, 0xA507, + 0x8C62, 0x9083, 0x9484, 0x9083, 0x94A4, 0x94A5, 0x98C5, 0x98C5, + 0xA107, 0xA107, 0xA107, 0xB18B, 0xA907, 0x9062, 0x9484, 0x9CE6, + 0x8842, 0x94A4, 0x9484, 0x9084, 0x8C62, 0x8C63, 0x9CC5, 0x9CC5, + 0x98C6, 0x8C63, 0x9484, 0xA0E6, 0x9CE6, 0x9084, 0x94A4, 0x90A5, + 0x8C63, 0x8C42, 0x8C62, 0x8C62, 0x8C63, 0xA108, 0xA94A, 0xA528, + 0x94A5, 0x8884, 0x8884, 0x8884, 0xB0A5, 0xBC84, 0xA483, 0xA484, + 0x8C63, 0x8C42, 0x8C63, 0x9083, 0xA94A, 0x9083, 0x8C62, 0x94A4, + 0x8884, 0x8063, 0x90A5, 0x94A4, 0xA483, 0xBC63, 0xA884, 0x8884, + 0x9083, 0x8C63, 0x8C42, 0x8C63, 0x9084, 0x8842, 0x9083, 0x9084, + 0x8C42, 0x8C62, 0x98C6, 0xAD6A, 0x9083, 0x8C63, 0x98C5, 0xA107, + 0x8400, 0xC1ED, 0xEF7B, 0xEF7B, 0x8400, 0xAD27, 0xEF7B, 0xEF7B, + 0x9CE6, 0x9CA4, 0xEB5A, 0xEB5A, 0x9CE6, 0x9062, 0xDAB4, 0xE739, + 0xE739, 0xE318, 0x9483, 0x8C63, 0xE318, 0xCE72, 0x9062, 0x9CC5, + 0xDEF7, 0xC20F, 0x8C41, 0x9CE6, 0xDAD6, 0xB9AC, 0x8C20, 0x9CC5, + 0xA0E6, 0xA528, 0x9CC5, 0xA528, 0xA508, 0x94A5, 0x98C6, 0xA108, + 0x9CE6, 0x9CC5, 0xA0E7, 0xA94A, 0xA0E6, 0xA0E7, 0xA507, 0xAD6B, + 0xA107, 0x98C6, 0x9CE6, 0x9083, 0x98C6, 0xA108, 0xA107, 0x98C5, + 0xB9CD, 0xB18B, 0xA107, 0x9CC6, 0xC210, 0xB9CE, 0xA528, 0x9CC6, + 0x98C5, 0x94A5, 0x9084, 0x8884, 0x9CC6, 0x9CE6, 0x9CC6, 0x94A5, + 0x9CE6, 0x9CE6, 0x9CE7, 0xA108, 0x98C5, 0x98C5, 0x98C6, 0x98C6, + 0xB0C6, 0xD0C6, 0xD0C6, 0xD0C6, 0x90A4, 0x90A4, 0x98A5, 0x9CA4, + 0x9CE6, 0x90A4, 0x9084, 0x9084, 0x98C6, 0x98C6, 0x98C6, 0x98C6, + 0xD0A5, 0xD0A5, 0xA484, 0x8483, 0x9484, 0x9083, 0x8C83, 0x9084, + 0x90A5, 0x94A5, 0x9CE6, 0x9CE6, 0x98C6, 0x98C6, 0x9CE6, 0x98C6, + 0x8C63, 0x9084, 0x9484, 0x9083, 0x98C5, 0x98C5, 0x94A4, 0x94A5, + 0x98C6, 0x98C6, 0x98C5, 0x98C5, 0x98C6, 0x98C6, 0x98C6, 0x98C6, + 0x9084, 0x8821, 0xCE51, 0xE739, 0x94A5, 0x8C20, 0xBDCE, 0xE318, + 0x98C5, 0x8821, 0xB18B, 0xE318, 0x98C6, 0x8842, 0xAD49, 0xDEF7, + 0xDAD6, 0xAD49, 0x8C41, 0xA508, 0xD6B5, 0xBDCC, 0x8C20, 0x8C41, + 0xD6B5, 0xD294, 0xB98A, 0xAD06, 0xD294, 0xCE73, 0xCE73, 0xCA52, + 0xA94A, 0xB5AD, 0xB18C, 0xAD6B, 0x9062, 0x9062, 0x9062, 0x9062, + 0xAD27, 0xAD06, 0xAD06, 0xAD06, 0xCA52, 0xC631, 0xC631, 0xC210, + 0xA94B, 0xB18C, 0xB58D, 0xAD6B, 0x9062, 0x9484, 0x98A4, 0x98A4, + 0xA906, 0xA906, 0xA506, 0xA907, 0xC210, 0xC210, 0xB9F0, 0xBDEF, + 0xA94B, 0xA94B, 0xA94B, 0xA94B, 0x98A5, 0x98A5, 0x98A4, 0x98A4, + 0xA907, 0xA907, 0xA907, 0xA506, 0xBDEF, 0xBDEF, 0xBDEF, 0xB1F2, + 0xA94B, 0xA94A, 0xA54A, 0xA529, 0x9484, 0x9484, 0x9483, 0x9483, + 0xA4E6, 0xA4E6, 0xA4E6, 0xA4E6, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, + 0xA529, 0xA529, 0xA529, 0xA108, 0x9062, 0x8C63, 0x9062, 0x9062, + 0xA4E6, 0x9CE6, 0xA0E6, 0xA506, 0xBDEF, 0xC210, 0xC210, 0xC210, + 0xA108, 0x9CE7, 0x9CE7, 0x98C6, 0x8C41, 0x8C42, 0x8C41, 0x8C41, + 0xA507, 0xA508, 0xAD27, 0xB127, 0xC631, 0xC631, 0xCA52, 0xCA52, + 0x98C6, 0x8C63, 0xA0E6, 0xDAD6, 0x8C41, 0x8400, 0xB548, 0xDAD6, + 0xB127, 0xB548, 0xD6B5, 0xD6B5, 0xCE73, 0xCE73, 0xD294, 0xD6B5, + 0xD294, 0xCA74, 0xBA56, 0xB635, 0x9A3B, 0x81FF, 0x81FF, 0x81FF, + 0x81FF, 0x8A1F, 0xA27F, 0xA27F, 0x81FF, 0xA27F, 0xFFFF, 0xFFFF, + 0xB635, 0xB214, 0xB214, 0xBE11, 0x81FF, 0x81FF, 0x81FF, 0x81FF, + 0xA27F, 0xA27F, 0xA27F, 0x8A1F, 0xFFFF, 0xFFFF, 0xFFFF, 0xDF7F, + 0xA1F7, 0x91FA, 0x81FF, 0x95F9, 0x81FF, 0x81FF, 0x8A1F, 0x81FF, + 0x81FF, 0xD75F, 0xBEFF, 0x81FF, 0x81FF, 0xFFFF, 0xBEFF, 0x81FF, + 0xB9CE, 0xB9CE, 0x8DFC, 0x81FF, 0xA9D2, 0xA9D2, 0x81FF, 0x9A5F, + 0x99D6, 0x99D6, 0x81FF, 0xBEFF, 0x99D6, 0x99D6, 0x81FF, 0xBEFF, + 0x85FD, 0x95F9, 0xB5CF, 0xB1F1, 0x81FF, 0x81FF, 0x95F9, 0x81FF, + 0xEFBF, 0x81FF, 0x85FD, 0x81FF, 0xFFFF, 0x81FF, 0x81FF, 0x81FF, + 0xA5F5, 0xA5F5, 0xB5F2, 0xB214, 0x81FF, 0x81FF, 0x81FF, 0x81FF, + 0xB2BF, 0xB2BF, 0x81FF, 0x9A5F, 0xDF7F, 0xDF7F, 0x81FF, 0xE79F, + 0xA218, 0xA218, 0xA218, 0xA639, 0x81FF, 0x81FF, 0x81FF, 0x81FF, + 0xBEFF, 0xBEFF, 0xBEFF, 0xBEFF, 0xF7DF, 0xDF7F, 0xDF7F, 0xDF7F, + 0xA639, 0xB657, 0xCA75, 0xD294, 0x81FF, 0x81FF, 0x861E, 0xCA95, + 0xBEFF, 0xAA9F, 0x81FF, 0xB658, 0xD75F, 0x8A1F, 0x81FF, 0xCA75, + 0x81FF, 0xA27F, 0xFFFF, 0xA27F, 0x81FF, 0xA27F, 0xFFFF, 0xFFFF, + 0x81FF, 0xA27F, 0xFFFF, 0xBADF, 0x81FF, 0xA27F, 0xFFFF, 0xA27F, + 0x81FF, 0x81FF, 0xCF3F, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xBADF, + 0xA27F, 0xA27F, 0xA27F, 0x81FF, 0x81FF, 0x81FF, 0x81FF, 0x81FF, + 0x923F, 0xFFFF, 0xBEFF, 0x81FF, 0x81FF, 0xFFFF, 0xBEFF, 0x81FF, + 0x81FF, 0xFFFF, 0xCF3F, 0xA27F, 0x81FF, 0xFFFF, 0xFFFF, 0xFFFF, + 0x99D6, 0x99D6, 0x81FF, 0xBEFF, 0x81FF, 0x81FF, 0x81FF, 0xBEFF, + 0xA27F, 0xA27F, 0x9A5F, 0xBADF, 0xFFFF, 0xFFFF, 0xA27F, 0x81FF, + 0xFFFF, 0x81FF, 0x81FF, 0x81FF, 0xFFFF, 0x81FF, 0x81FF, 0x81FF, + 0xFFFF, 0xBEFF, 0xBEFF, 0xBEFF, 0xC71F, 0xDF7F, 0xDF7F, 0xDF7F, + 0xDF7F, 0xDF7F, 0x923F, 0xF7DF, 0xDF7F, 0xDF7F, 0x81FF, 0xAA9F, + 0xEFBF, 0xC71F, 0x81FF, 0x9A5F, 0xCF3F, 0x81FF, 0x8A1F, 0xD75F, + 0xE79F, 0xBEFF, 0xBEFF, 0xBEFF, 0xDF7F, 0xDF7F, 0xDF7F, 0xDF7F, + 0xBEFF, 0xBEFF, 0xBEFF, 0xC71F, 0xDF7F, 0xDF7F, 0xDF7F, 0xDF7F, + 0xBEFF, 0x81FF, 0x81FF, 0xB657, 0xFFFF, 0xC71F, 0x81FF, 0xA23A, + 0xFFFF, 0xC71F, 0x81FF, 0xA23A, 0xD75F, 0x8A1F, 0x81FF, 0xB658, + 0x81FF, 0x9A5F, 0xAA9F, 0x81FF, 0x921D, 0x81FF, 0x81FF, 0x85FE, + 0xD294, 0xBE55, 0xB657, 0xC653, 0xD294, 0xD294, 0xCE73, 0xCA52, + 0x8A1D, 0xB214, 0xB214, 0x8DFC, 0xBA34, 0xC631, 0xC210, 0xB612, + 0xC631, 0xC631, 0xC631, 0xC210, 0xCA52, 0xCA52, 0xC631, 0xC631, + 0x81FF, 0x81FF, 0x81FF, 0x81FF, 0x8DFC, 0x81FF, 0x81FF, 0x81FF, + 0xC210, 0xBE10, 0xBDEF, 0xBDEF, 0xC210, 0xC210, 0xC210, 0xBE10, + 0x81FF, 0x81FF, 0x81FF, 0x81FF, 0x81FF, 0x81FF, 0x8DFB, 0xA5D4, + 0xBDEF, 0xB9CE, 0xB9CE, 0xB9CE, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, + 0x81FF, 0x81FF, 0x81FF, 0x81FF, 0x99F8, 0x8DFB, 0x8DFB, 0x8DFB, + 0xB9CE, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBDEF, 0xBE10, 0xC210, + 0x81FF, 0x81FF, 0x81FF, 0x81FF, 0x95F9, 0xA5F5, 0xA1F7, 0x91FA, + 0xBDEF, 0xBE10, 0xC210, 0xC210, 0xC210, 0xC210, 0xC631, 0xC631, + 0x81FF, 0x81FF, 0x81FF, 0x81FF, 0x921C, 0x921C, 0x921C, 0x921C, + 0xC631, 0xC631, 0xCA52, 0xCA52, 0xC631, 0xCA52, 0xCA52, 0xCE73, + 0x81FF, 0x81FF, 0x9A3B, 0xD294, 0x961B, 0xAA39, 0xD294, 0xD294, + 0xCE73, 0xCE73, 0xD294, 0xD6B5, 0xCE73, 0xD294, 0xD6B5, 0xD6B5, +}; diff --git a/genplus-gx/gx/gx_audio.c b/genplus-gx/gx/gx_audio.c new file mode 100644 index 0000000000..b237c0e8d7 --- /dev/null +++ b/genplus-gx/gx/gx_audio.c @@ -0,0 +1,210 @@ +/**************************************************************************** + * gx_audio.c + * + * Genesis Plus GX audio support + * + * Copyright Eke-Eke (2007-2013), based on original work from Softdev (2006) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +/* Length is dimensionned for at least one frame of emulation */ +#define SOUND_BUFFER_LEN 4096 + +/* Number of sound buffers */ +#define SOUND_BUFFER_NUM 3 + +/* audio DMA status */ +u32 audioStarted; + +/* DMA soundbuffers (required to be 32-bytes aligned) */ +static u8 soundbuffer[SOUND_BUFFER_NUM][SOUND_BUFFER_LEN] ATTRIBUTE_ALIGN(32); + +/* Current work soundbuffer */ +static u8 mixbuffer; + +/* Background music */ +static u8 *Bg_music_ogg = NULL; +static u32 Bg_music_ogg_size = 0; + +/* Frame Sync */ +u32 audioSync; +static u32 audioWait; + +/***************************************************************************************/ +/* Audio engine */ +/***************************************************************************************/ + +/* Audio DMA callback */ +static void ai_callback(void) +{ + audioWait = 0; +} + +/* AUDIO engine initialization */ +void gx_audio_Init(void) +{ + /* Initialize AUDIO processing library (ASNDLIB) */ + /* AUDIO & DSP hardware are initialized */ + /* Default samplerate is set to 48kHz */ + ASND_Init(); + + /* Load background music from FAT device */ + char fname[MAXPATHLEN]; + sprintf(fname,"%s/Bg_music.ogg",DEFAULT_PATH); + FILE *f = fopen(fname,"rb"); + if (f) + { + struct stat filestat; + stat(fname, &filestat); + Bg_music_ogg_size = filestat.st_size; + Bg_music_ogg = memalign(32,Bg_music_ogg_size); + if (Bg_music_ogg) + { + fread(Bg_music_ogg,1,Bg_music_ogg_size,f); + } + fclose(f); + } + + /* emulation is synchronized with audio hardware by default */ + audioSync = 1; +} + +/* AUDIO engine shutdown */ +void gx_audio_Shutdown(void) +{ + PauseOgg(1); + StopOgg(); + ASND_Pause(1); + ASND_End(); + if (Bg_music_ogg) + { + free(Bg_music_ogg); + } +} + +/*** + gx_audio_Update + + This function retrieves samples for the frame then set the next DMA parameters + Parameters will be taken in account only when current DMA operation is over + ***/ +int gx_audio_Update(void) +{ + if (!audioWait) + { + /* Current available soundbuffer */ + s16 *sb = (s16 *)(soundbuffer[mixbuffer]); + + /* Retrieve audio samples (size must be multiple of 32 bytes) */ + int size = audio_update(sb) * 4; + + /* Update DMA settings */ + DCFlushRange((void *)sb, size); + AUDIO_InitDMA((u32) sb, size); + mixbuffer = (mixbuffer + 1) % SOUND_BUFFER_NUM; + audioWait = audioSync; + + /* Start Audio DMA */ + /* this is called once to kick-off DMA from external memory to audio interface */ + /* DMA operation is automatically restarted when all samples have been sent. */ + /* If DMA settings are not updated at that time, previous sound buffer will be used. */ + /* Therefore we need to make sure frame emulation is completed before current DMA is */ + /* completed, by synchronizing frame emulation with DMA start and also by syncing it */ + /* with Video Interrupt and outputing a suitable number of samples per frame. */ + if (!audioStarted) + { + /* restart audio DMA */ + AUDIO_StopDMA(); + AUDIO_StartDMA(); + audioStarted = 1; + } + + return SYNC_AUDIO; + } + + return SYNC_WAIT; +} + +/*** + gx_audio_Start + + This function restart the audio engine + This is called when coming back from Main Menu + ***/ +void gx_audio_Start(void) +{ + /* shutdown background music */ + PauseOgg(1); + StopOgg(); + + /* shutdown menu audio processing */ + ASND_Pause(1); + ASND_End(); + AUDIO_StopDMA(); + AUDIO_RegisterDMACallback(NULL); + DSP_Halt(); + + /* DMA Interrupt callback */ + AUDIO_RegisterDMACallback(ai_callback); + + /* reset emulation audio processing */ + memset(soundbuffer, 0, sizeof(soundbuffer)); + audioStarted = 0; + mixbuffer = 0; + audioWait = 0; +} + +/*** + gx_audio_Stop + + This function stops current Audio DMA process + This is called when going back to Main Menu + DMA need to be restarted when going back to the game (see above) + ***/ +void gx_audio_Stop(void) +{ + /* restart menu audio processing */ + DSP_Unhalt(); + ASND_Init(); + ASND_Pause(0); + + /* play background music */ + if (Bg_music_ogg && !Shutdown) + { + PauseOgg(0); + PlayOgg((char *)Bg_music_ogg, Bg_music_ogg_size, 0, OGG_INFINITE_TIME); + SetVolumeOgg(((int)config.bgm_volume * 255) / 100); + } +} diff --git a/genplus-gx/gx/gx_audio.h b/genplus-gx/gx/gx_audio.h new file mode 100644 index 0000000000..174a3ca45b --- /dev/null +++ b/genplus-gx/gx/gx_audio.h @@ -0,0 +1,52 @@ +/**************************************************************************** + * gx_audio.c + * + * Genesis Plus GX audio support + * + * Copyright Eke-Eke (2007-2013), based on original work from Softdev (2006) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _GC_AUDIO_H_ +#define _GC_AUDIO_H_ + +extern u32 audioStarted; +extern u32 audioSync; + +extern void gx_audio_Init(void); +extern void gx_audio_Shutdown(void); +extern void gx_audio_Start(void); +extern void gx_audio_Stop(void); +extern int gx_audio_Update(void); + +#endif diff --git a/genplus-gx/gx/gx_input.c b/genplus-gx/gx/gx_input.c new file mode 100644 index 0000000000..b175cb2500 --- /dev/null +++ b/genplus-gx/gx/gx_input.c @@ -0,0 +1,1641 @@ +/**************************************************************************** + * gx_input.c + * + * Genesis Plus GX input support + * + * Copyright Eke-Eke (2007-2013) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "font.h" +#include "gui.h" +#include "cheats.h" + +#ifdef HW_RVL +#include +#endif + +/* Analog sticks sensitivity */ +#define ANALOG_SENSITIVITY 30 + +/* Delay before held keys triggering */ +/* higher is the value, less responsive is the key update */ +#define HELD_DELAY 30 + +/* Direction & selection update speed when a key is being held */ +/* lower is the value, faster is the key update */ +#define HELD_SPEED 4 + + +/* Configurable keys */ +#define KEY_BUTTONA 0 +#define KEY_BUTTONB 1 +#define KEY_BUTTONC 2 +#define KEY_START 3 +#define KEY_BUTTONX 4 +#define KEY_BUTTONY 5 +#define KEY_BUTTONZ 6 +#define KEY_MODE 7 +#define KEY_MENU 8 + +#ifdef HW_RVL + +#define PAD_UP 0 +#define PAD_DOWN 1 +#define PAD_LEFT 2 +#define PAD_RIGHT 3 + +/* default directions mapping */ +static u32 wpad_dirmap[3][4] = +{ + {WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT, WPAD_BUTTON_UP, WPAD_BUTTON_DOWN}, /* WIIMOTE */ + {WPAD_BUTTON_UP, WPAD_BUTTON_DOWN, WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT}, /* WIIMOTE + NUNCHUK */ + {WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN, WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT} /* CLASSIC */ +}; + +#define WPAD_BUTTONS_HELD (WPAD_BUTTON_UP | WPAD_BUTTON_DOWN | WPAD_BUTTON_LEFT | WPAD_BUTTON_RIGHT | \ + WPAD_BUTTON_MINUS | WPAD_BUTTON_PLUS | WPAD_BUTTON_A | WPAD_BUTTON_2 | \ + WPAD_CLASSIC_BUTTON_UP | WPAD_CLASSIC_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_LEFT | WPAD_CLASSIC_BUTTON_RIGHT | \ + WPAD_CLASSIC_BUTTON_FULL_L | WPAD_CLASSIC_BUTTON_FULL_R | WPAD_CLASSIC_BUTTON_A) + +#endif + +#define PAD_BUTTONS_HELD (PAD_BUTTON_UP | PAD_BUTTON_DOWN | PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | \ + PAD_TRIGGER_L | PAD_TRIGGER_R | PAD_BUTTON_A) + +static char keyname[MAX_KEYS][16]; + +static int held_cnt = 0; +static int inputs_disabled = 0; + +/***************************************************************************************/ +/* Gamecube PAD support */ +/***************************************************************************************/ +static void pad_config(int chan, int first_key, int last_key) +{ + u16 p = 0; + char msg[64]; + + /* disable background PAD scanning */ + inputs_disabled = 1; + + /* Check if PAD is connected */ + VIDEO_WaitVSync(); + if (!(PAD_ScanPads() & (1< ANALOG_SENSITIVITY) + { + ConfigRequested = 1; + return; + } + + /* D-PAD */ + if ((p & PAD_BUTTON_UP) || (y > ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_UP; + else if ((p & PAD_BUTTON_DOWN) || (y < -ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_DOWN; + if ((p & PAD_BUTTON_LEFT) || (x < -ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_LEFT; + else if ((p & PAD_BUTTON_RIGHT) || (x > ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_RIGHT; + + /* Buttons */ + if (p & pad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_A; + if (p & pad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_B; + if (p & pad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_C; + if (p & pad_keymap[KEY_START]) input.pad[i] |= INPUT_START; + + break; + } + + case DEVICE_XE_A1P: + { + /* Left Stick analog position [0-255] */ + input.analog[i][0] = (x + 128); + input.analog[i][1] = y ? (127 - y) : (128 - y); + + /* Right Stick analog position [0-255] */ + x = PAD_SubStickX(chan); + y = PAD_SubStickY(chan); + + /* Emulated stick is unidirectional but can be rotated */ + if (abs(x) > abs(y)) + { + input.analog[i+1][0] = (x + 128); + } + else + { + input.analog[i+1][0] = (y + 128); + } + + /* Buttons */ + if (p & pad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_XE_A; + if (p & pad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_XE_B; + if (p & pad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_XE_C; + if (p & pad_keymap[KEY_START]) input.pad[i] |= INPUT_XE_START; + if (p & pad_keymap[KEY_BUTTONX]) input.pad[i] |= INPUT_XE_D; + if (p & pad_keymap[KEY_BUTTONY]) input.pad[i] |= INPUT_XE_E1; + if (p & pad_keymap[KEY_BUTTONZ]) input.pad[i] |= INPUT_XE_E2; + if (p & pad_keymap[KEY_MODE]) input.pad[i] |= INPUT_XE_SELECT; + + break; + } + + case DEVICE_SPORTSPAD: + { + /* Y analog position [0-255] */ + input.analog[i][1] = y ? (127 - y) : (128 - y); + + /* default inputs are checked below */ + } + + case DEVICE_PADDLE: + { + /* Default menu key (right analog stick) */ + if (PAD_SubStickX(chan) > ANALOG_SENSITIVITY) + { + ConfigRequested = 1; + return; + } + + /* X analog position [0-255] */ + input.analog[i][0] = (x + 128); + + /* Buttons */ + if (p & pad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_BUTTON1; + if (p & pad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_BUTTON2; + if (p & pad_keymap[KEY_START]) input.pad[i] |= INPUT_START; + + break; + } + + case DEVICE_PAD2B: + { + /* Default menu key (right analog stick) */ + if (PAD_SubStickX(chan) > ANALOG_SENSITIVITY) + { + ConfigRequested = 1; + return; + } + + /* D-PAD */ + if ((p & PAD_BUTTON_UP) || (y > ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_UP; + else if ((p & PAD_BUTTON_DOWN) || (y < -ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_DOWN; + if ((p & PAD_BUTTON_LEFT) || (x < -ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_LEFT; + else if ((p & PAD_BUTTON_RIGHT) || (x > ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_RIGHT; + + /* Buttons */ + if (p & pad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_BUTTON1; + if (p & pad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_BUTTON2; + if (p & pad_keymap[KEY_START]) input.pad[i] |= INPUT_START; + + break; + } + + case DEVICE_LIGHTGUN: + { + /* Default menu key (right analog stick) */ + if (PAD_SubStickX(chan) > ANALOG_SENSITIVITY) + { + ConfigRequested = 1; + return; + } + + /* Gun screen position (x,y) */ + input.analog[i][0] += x / ANALOG_SENSITIVITY; + input.analog[i][1] -= y / ANALOG_SENSITIVITY; + + /* Limits */ + if (input.analog[i][0] < 0) input.analog[i][0] = 0; + else if (input.analog[i][0] > bitmap.viewport.w) input.analog[i][0] = bitmap.viewport.w; + if (input.analog[i][1] < 0) input.analog[i][1] = 0; + else if (input.analog[i][1] > bitmap.viewport.h) input.analog[i][1] = bitmap.viewport.h; + + /* Buttons */ + if (p & pad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_A; + if (p & pad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_B; + if (p & pad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_C; + if (p & pad_keymap[KEY_START]) input.pad[i] |= INPUT_START; + + break; + } + + case DEVICE_MOUSE: + { + /* Default menu key (right analog stick) */ + if (PAD_SubStickX(chan) > ANALOG_SENSITIVITY) + { + ConfigRequested = 1; + return; + } + + /* Mouse relative movement (-255,255) */ + input.analog[i][0] = (x / ANALOG_SENSITIVITY) * 2; + input.analog[i][1] = (y / ANALOG_SENSITIVITY) * 2; + + /* Y-Axis inversion */ + if (config.invert_mouse) + { + input.analog[i][1] = -input.analog[i][1]; + } + + /* Buttons */ + if (p & pad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_MOUSE_CENTER; + if (p & pad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_MOUSE_LEFT; + if (p & pad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_MOUSE_RIGHT; + if (p & pad_keymap[KEY_START]) input.pad[i] |= INPUT_START; + + break; + } + + case DEVICE_PICO: + { + /* Default menu key (right analog stick) */ + if (PAD_SubStickX(chan) > ANALOG_SENSITIVITY) + { + ConfigRequested = 1; + return; + } + + /* D-PAD */ + if (p & PAD_BUTTON_UP) input.pad[0] |= INPUT_UP; + else if (p & PAD_BUTTON_DOWN) input.pad[0] |= INPUT_DOWN; + if (p & PAD_BUTTON_LEFT) input.pad[0] |= INPUT_LEFT; + else if (p & PAD_BUTTON_RIGHT) input.pad[0] |= INPUT_RIGHT; + + /* PEN screen position (x,y) */ + input.analog[0][0] += x / ANALOG_SENSITIVITY; + input.analog[0][1] -= y / ANALOG_SENSITIVITY; + + /* Limits */ + if (input.analog[0][0] < 0x17c) input.analog[0][0] = 0x17c; + else if (input.analog[0][0] > 0x3c) input.analog[0][0] = 0x3c; + if (input.analog[0][1] < 0x1fc) input.analog[0][1] = 0x1fc; + else if (input.analog[0][1] > 0x3f3) input.analog[0][1] = 0x3f3; + + /* PEN button */ + if (p & pad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_PICO_RED; + + /* RED button */ + if (p & pad_keymap[KEY_BUTTONB]) input.pad[0] |= INPUT_PICO_PEN; + + /* PAGE index increment */ + if (p & pad_keymap[KEY_BUTTONC]) pico_current = (pico_current + 1) & 7; + + break; + } + + case DEVICE_TEREBI: + { + /* Default menu key (right analog stick) */ + if (PAD_SubStickX(chan) > ANALOG_SENSITIVITY) + { + ConfigRequested = 1; + return; + } + + /* PEN screen position (x,y) */ + input.analog[0][0] += x / ANALOG_SENSITIVITY; + input.analog[0][1] -= y / ANALOG_SENSITIVITY; + + /* Limits */ + if (input.analog[0][0] < 0) input.analog[0][0] = 0; + else if (input.analog[0][0] > 250) input.analog[0][0] = 250; + if (input.analog[0][1] < 0) input.analog[0][1] = 0; + else if (input.analog[0][1] > 250) input.analog[0][1] = 250; + + /* PEN button */ + if (p & pad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_BUTTON1; + + break; + } + + case DEVICE_ACTIVATOR: + { + /* Left & right analog stick angle [0-360] */ + float ang; + + /* Left stick values */ + if ((abs(x) > ANALOG_SENSITIVITY) || (abs(y) > ANALOG_SENSITIVITY)) + { + /* Calculate angle (in degree) */ + ang = 90.0 - (atan((float)y / (float)x) * 180.0 / M_PI); + if (x < 0) ang += 180.0; + + /* 8 bottom sensors = 8 areas */ + if ((ang > 22.5) && (ang <= 67.5)) input.pad[i] |= INPUT_ACTIVATOR_2L; + else if ((ang > 67.5) && (ang <= 112.5)) input.pad[i] |= INPUT_ACTIVATOR_3L; + else if ((ang > 112.5) && (ang <= 157.5)) input.pad[i] |= INPUT_ACTIVATOR_4L; + else if ((ang > 157.5) && (ang <= 202.5)) input.pad[i] |= INPUT_ACTIVATOR_5L; + else if ((ang > 202.5) && (ang <= 247.5)) input.pad[i] |= INPUT_ACTIVATOR_6L; + else if ((ang > 247.5) && (ang <= 292.5)) input.pad[i] |= INPUT_ACTIVATOR_7L; + else if ((ang > 292.5) && (ang <= 337.5)) input.pad[i] |= INPUT_ACTIVATOR_8L; + else input.pad[i] |= INPUT_ACTIVATOR_1L; + } + + /* Right stick values */ + x = PAD_SubStickX(chan); + y = PAD_SubStickY(chan); + + if ((abs(x) > ANALOG_SENSITIVITY) || (abs(y) > ANALOG_SENSITIVITY)) + { + /* Calculate angle (in degree) */ + ang = 90.0 - (atan((float)y / (float)x) * 180.0 / M_PI); + if (x < 0) ang += 180.0; + + /* 8 top sensors = 8 areas */ + if ((ang > 22.5) && (ang <= 67.5)) input.pad[i] |= INPUT_ACTIVATOR_2U; + else if ((ang > 67.5) && (ang <= 112.5)) input.pad[i] |= INPUT_ACTIVATOR_3U; + else if ((ang > 112.5) && (ang <= 157.5)) input.pad[i] |= INPUT_ACTIVATOR_4U; + else if ((ang > 157.5) && (ang <= 202.5)) input.pad[i] |= INPUT_ACTIVATOR_5U; + else if ((ang > 202.5) && (ang <= 247.5)) input.pad[i] |= INPUT_ACTIVATOR_6U; + else if ((ang > 247.5) && (ang <= 292.5)) input.pad[i] |= INPUT_ACTIVATOR_7U; + else if ((ang > 292.5) && (ang <= 337.5)) input.pad[i] |= INPUT_ACTIVATOR_8U; + else input.pad[i] |= INPUT_ACTIVATOR_1U; + } + + break; + } + } +} + +/***************************************************************************************/ +/* Wii WPAD support */ +/***************************************************************************************/ +#ifdef HW_RVL + +static int wpad_StickX(WPADData *data, u8 right) +{ + struct joystick_t* js = NULL; + + switch (data->exp.type) + { + case WPAD_EXP_NUNCHUK: + js = right ? NULL : &data->exp.nunchuk.js; + break; + + case WPAD_EXP_CLASSIC: + js = right ? &data->exp.classic.rjs : &data->exp.classic.ljs; + break; + + default: + break; + } + + if (js) + { + /* raw X value */ + int x = js->pos.x; + + /* value returned is sometime above calibrated limits */ + if (x > js->max.x) return 127; + if (x < js->min.x) return -128; + + /* adjust against center position */ + x -= js->center.x; + + /* return interpolated range [-128;127] */ + if (x > 0) + { + return (int)(127.0 * ((float)x / (float)(js->max.x - js->center.x))); + } + { + return (int)(128.0 * ((float)x / (float)(js->center.x - js->min.x))); + } + } + + return 0; +} + +static int wpad_StickY(WPADData *data, u8 right) +{ + struct joystick_t* js = NULL; + + switch (data->exp.type) + { + case WPAD_EXP_NUNCHUK: + js = right ? NULL : &data->exp.nunchuk.js; + break; + + case WPAD_EXP_CLASSIC: + js = right ? &data->exp.classic.rjs : &data->exp.classic.ljs; + break; + + default: + break; + } + + if (js) + { + /* raw Y value */ + int y = js->pos.y; + + /* value returned is sometime above calibrated limits */ + if (y > js->max.y) return 127; + if (y < js->min.y) return -128; + + /* adjust against center position */ + y -= js->center.y; + + /* return interpolated range [-128;127] */ + if (y > 0) + { + return (int)(127.0 * ((float)y / (float)(js->max.y - js->center.y))); + } + { + return (int)(128.0 * ((float)y / (float)(js->center.y - js->min.y))); + } + } + + return 0; +} + +static void wpad_config(u8 exp, int chan, int first_key, int last_key) +{ + char msg[64]; + u32 p = 255; + + /* Disable background PAD scanning */ + inputs_disabled = 1; + + /* Check if device is connected */ + WPAD_Probe(chan, &p); + if (((exp > WPAD_EXP_NONE) && (p != exp)) || (p == 255)) + { + /* device not detected */ + if (exp == WPAD_EXP_NONE) sprintf(msg, "WIIMOTE #%d is not connected !", chan+1); + if (exp == WPAD_EXP_NUNCHUK) sprintf(msg, "NUNCHUK #%d is not connected !", chan+1); + if (exp == WPAD_EXP_CLASSIC) sprintf(msg, "CLASSIC #%d is not connected !", chan+1); + GUI_WaitPrompt("Error",msg); + + /* re-enable background PAD scanning and exit */ + inputs_disabled = 0; + return; + } + + /* Configure each keys */ + do + { + /* ignore unused keys */ + if (strcmp(keyname[first_key], "N.A")) + { + /* remove any pending buttons */ + while (WPAD_ButtonsHeld(chan)) + { + VIDEO_WaitVSync(); + WPAD_ScanPads(); + } + + /* configurable button */ + sprintf(msg,"Press key for %s\n(HOME to return)",keyname[first_key]); + GUI_MsgBoxUpdate(0,msg); + + /* wait for user input */ + p = 0; + while (!p) + { + VIDEO_WaitVSync(); + WPAD_ScanPads(); + p = WPAD_ButtonsDown(chan); + } + + /* detect pressed key */ + switch (exp) + { + /* Wiimote (TODO: add motion sensing !) */ + case WPAD_EXP_NONE: + { + if (p & WPAD_BUTTON_2) p = WPAD_BUTTON_2; + else if (p & WPAD_BUTTON_1) p = WPAD_BUTTON_1; + else if (p & WPAD_BUTTON_B) p = WPAD_BUTTON_B; + else if (p & WPAD_BUTTON_A) p = WPAD_BUTTON_A; + else if (p & WPAD_BUTTON_PLUS) p = WPAD_BUTTON_PLUS; + else if (p & WPAD_BUTTON_MINUS) p = WPAD_BUTTON_MINUS; + else first_key = MAX_KEYS; + break; + } + + /* Wiimote + Nunchuk (TODO: add motion sensing !) */ + case WPAD_EXP_NUNCHUK: + { + if (p & WPAD_BUTTON_2) p = WPAD_BUTTON_2; + else if (p & WPAD_BUTTON_1) p = WPAD_BUTTON_1; + else if (p & WPAD_BUTTON_B) p = WPAD_BUTTON_B; + else if (p & WPAD_BUTTON_A) p = WPAD_BUTTON_A; + else if (p & WPAD_BUTTON_PLUS) p = WPAD_BUTTON_PLUS; + else if (p & WPAD_BUTTON_MINUS) p= WPAD_BUTTON_MINUS; + else if (p & WPAD_NUNCHUK_BUTTON_Z) p = WPAD_NUNCHUK_BUTTON_Z; + else if (p & WPAD_NUNCHUK_BUTTON_C) p = WPAD_NUNCHUK_BUTTON_C; + else first_key = MAX_KEYS; + break; + } + + /* Classic Controller */ + case WPAD_EXP_CLASSIC: + { + if (p & WPAD_CLASSIC_BUTTON_X) p = WPAD_CLASSIC_BUTTON_X; + else if (p & WPAD_CLASSIC_BUTTON_A) p = WPAD_CLASSIC_BUTTON_A; + else if (p & WPAD_CLASSIC_BUTTON_Y) p = WPAD_CLASSIC_BUTTON_Y; + else if (p & WPAD_CLASSIC_BUTTON_B) p = WPAD_CLASSIC_BUTTON_B; + else if (p & WPAD_CLASSIC_BUTTON_ZL) p = WPAD_CLASSIC_BUTTON_ZL; + else if (p & WPAD_CLASSIC_BUTTON_ZR) p = WPAD_CLASSIC_BUTTON_ZR; + else if (p & WPAD_CLASSIC_BUTTON_PLUS) p = WPAD_CLASSIC_BUTTON_PLUS; + else if (p & WPAD_CLASSIC_BUTTON_MINUS) p = WPAD_CLASSIC_BUTTON_MINUS; + else if (p & WPAD_CLASSIC_BUTTON_FULL_L) p = WPAD_CLASSIC_BUTTON_FULL_L; + else if (p & WPAD_CLASSIC_BUTTON_FULL_R) p = WPAD_CLASSIC_BUTTON_FULL_R; + else first_key = MAX_KEYS; + break; + } + + default: + { + first_key = MAX_KEYS; + break; + } + } + + /* update key mapping */ + if (first_key < MAX_KEYS) + { + config.wpad_keymap[exp + (chan * 3)][first_key] = p; + } + } + } + while (first_key++ < last_key); + + /* remove any pending buttons */ + while (WPAD_ButtonsHeld(chan)) + { + VIDEO_WaitVSync(); + WPAD_ScanPads(); + } + + /* re-enable background PAD scanning and exit */ + inputs_disabled = 0; +} + +static void wpad_update(s8 chan, u8 i, u32 exp) +{ + /* WPAD data */ + WPADData *data = WPAD_Data(chan); + + /* WPAD status */ + u32 p = data->btns_h; + + /* Analog sticks */ + s8 x = 0; + s8 y = 0; + + if (exp != WPAD_EXP_NONE) + { + x = wpad_StickX(data,0); + y = wpad_StickY(data,0); + } + + /* Retrieve current key mapping */ + u32 *wpad_keymap = config.wpad_keymap[exp + (chan * 3)]; + + /* Emulated device */ + switch (input.dev[i]) + { + case DEVICE_PAD6B: + { + /* Extra buttons */ + if (p & wpad_keymap[KEY_BUTTONX]) input.pad[i] |= INPUT_X; + if (p & wpad_keymap[KEY_BUTTONY]) input.pad[i] |= INPUT_Y; + if (p & wpad_keymap[KEY_BUTTONZ]) input.pad[i] |= INPUT_Z; + if (p & wpad_keymap[KEY_MODE]) input.pad[i] |= INPUT_MODE; + } + + case DEVICE_PAD3B: + { + /* D- PAD */ + if ((p & wpad_dirmap[exp][PAD_UP]) || (y > ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_UP; + else if ((p & wpad_dirmap[exp][PAD_DOWN]) || (y < -ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_DOWN; + if ((p & wpad_dirmap[exp][PAD_LEFT]) || (x < -ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_LEFT; + else if ((p & wpad_dirmap[exp][PAD_RIGHT]) || (x > ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_RIGHT; + + /* Buttons */ + if (p & wpad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_A; + if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_B; + if (p & wpad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_C; + if (p & wpad_keymap[KEY_START]) input.pad[i] |= INPUT_START; + + break; + } + + case DEVICE_XE_A1P: + { + /* Left Stick analog position [0-255] */ + input.analog[i][0] = (x + 128); + input.analog[i][1] = y ? (127 - y) : (128 - y); + + /* Right Stick analog position [0-255] */ + if (exp == WPAD_EXP_CLASSIC) + { + /* Classic Controller right stick */ + x = wpad_StickX(data,1); + y = wpad_StickY(data,1); + + /* Emulated stick is unidirectional but can be rotated */ + if (abs(x) > abs(y)) + { + input.analog[i+1][0] = (x + 128); + } + else + { + input.analog[i+1][0] = (y + 128); + } + } + else + { + /* Wiimote D-PAD */ + if ((p & wpad_dirmap[exp][PAD_DOWN]) || (p & wpad_dirmap[exp][PAD_LEFT])) input.analog[i+1][0]-=2; + else if ((p & wpad_dirmap[exp][PAD_UP]) || (p & wpad_dirmap[exp][PAD_RIGHT])) input.analog[i+1][0]+=2; + + /* Limits */ + if (input.analog[i+1][0] < 0) input.analog[i+1][0] = 0; + else if (input.analog[i+1][0] > 255) input.analog[i+1][0] = 255; + } + + /* Buttons */ + if (p & wpad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_XE_A; + if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_XE_B; + if (p & wpad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_XE_C; + if (p & wpad_keymap[KEY_START]) input.pad[i] |= INPUT_XE_START; + if (p & wpad_keymap[KEY_BUTTONX]) input.pad[i] |= INPUT_XE_D; + if (p & wpad_keymap[KEY_BUTTONY]) input.pad[i] |= INPUT_XE_E1; + if (p & wpad_keymap[KEY_BUTTONZ]) input.pad[i] |= INPUT_XE_E2; + if (p & wpad_keymap[KEY_MODE]) input.pad[i] |= INPUT_XE_SELECT; + + break; + } + + case DEVICE_SPORTSPAD: + { + /* X analog position [0-255] */ + if (p & wpad_dirmap[exp][PAD_LEFT]) input.analog[i][0]-=2; + else if (p & wpad_dirmap[exp][PAD_RIGHT]) input.analog[i][0]+=2; + else input.analog[i][0] = (x + 128); + + /* Y analog position [0-255] */ + if (p & wpad_dirmap[exp][PAD_UP]) input.analog[i][1]-=2; + else if (p & wpad_dirmap[exp][PAD_DOWN]) input.analog[i][1]+=2; + else input.analog[i][1] = y ? (127 - y) : (128 - y); + + /* Limits */ + if (input.analog[i][0] < 0) input.analog[i][0] = 0; + else if (input.analog[i][0] > 255) input.analog[i][0] = 255; + if (input.analog[i][1] < 0) input.analog[i][1] = 0; + else if (input.analog[i][1] > 255) input.analog[i][1] = 255; + + /* Buttons */ + if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_BUTTON1; + if (p & wpad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_BUTTON2; + if (p & wpad_keymap[KEY_START]) input.pad[i] |= INPUT_START; + + break; + } + + case DEVICE_PADDLE: + { + /* X analog position [0-255] */ + if (exp == WPAD_EXP_NONE) + { + /* Wiimote D-PAD */ + if (p & wpad_dirmap[exp][PAD_LEFT]) input.analog[i][0]-=2; + else if (p & wpad_dirmap[exp][PAD_RIGHT]) input.analog[i][0]+=2; + + /* Limits */ + if (input.analog[i][0] < 0) input.analog[i][0] = 0; + else if (input.analog[i][0] > 255) input.analog[i][0] = 255; + } + else + { + /* Left analog stick */ + input.analog[i][0] = (x + 128); + } + + /* Buttons */ + if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_BUTTON1; + if (p & wpad_keymap[KEY_START]) input.pad[i] |= INPUT_START; + + break; + } + + case DEVICE_PAD2B: + { + /* D-PAD */ + if ((p & wpad_dirmap[exp][PAD_UP]) || (y > ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_UP; + else if ((p & wpad_dirmap[exp][PAD_DOWN]) || (y < -ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_DOWN; + if ((p & wpad_dirmap[exp][PAD_LEFT]) || (x < -ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_LEFT; + else if ((p & wpad_dirmap[exp][PAD_RIGHT]) || (x > ANALOG_SENSITIVITY)) input.pad[i] |= INPUT_RIGHT; + + /* Buttons */ + if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_BUTTON1; + if (p & wpad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_BUTTON2; + if (p & wpad_keymap[KEY_START]) input.pad[i] |= INPUT_START; + + break; + } + + case DEVICE_LIGHTGUN: + { + /* Gun screen position (x,y) */ + if (exp != WPAD_EXP_CLASSIC) + { + /* Wiimote IR */ + struct ir_t ir; + WPAD_IR(chan, &ir); + + if (ir.valid) + { + /* screen position */ + input.analog[i][0] = (ir.x * bitmap.viewport.w) / 640; + input.analog[i][1] = (ir.y * bitmap.viewport.h) / 480; + } + else + { + /* lightgun should point outside screen area */ + input.analog[i][0] = 512; + input.analog[i][1] = 512; + } + } + else + { + /* Classic Controller analog stick */ + input.analog[i][0] += x / ANALOG_SENSITIVITY; + input.analog[i][1] -= y / ANALOG_SENSITIVITY; + + /* Limits */ + if (input.analog[i][0] < 0) input.analog[i][0] = 0; + else if (input.analog[i][0] > bitmap.viewport.w) input.analog[i][0] = bitmap.viewport.w; + if (input.analog[i][1] < 0) input.analog[i][1] = 0; + else if (input.analog[i][1] > bitmap.viewport.h) input.analog[i][1] = bitmap.viewport.h; + } + + /* Buttons */ + if (p & wpad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_A; + if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_B; + if (p & wpad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_C; + if (p & wpad_keymap[KEY_START]) input.pad[i] |= INPUT_START; + + break; + } + + case DEVICE_MOUSE: + { + /* Mouse relative movement (-255,255) */ + input.analog[i][0] = (x / ANALOG_SENSITIVITY) * 2; + input.analog[i][1] = (y / ANALOG_SENSITIVITY) * 2; + + /* Wiimote IR (buggy) */ + if (exp != WPAD_EXP_CLASSIC) + { + struct ir_t ir; + WPAD_IR(chan, &ir); + + /* Only if Wiimote is pointed to screen */ + if(ir.smooth_valid) + { + input.analog[i][0] = (int)((ir.sx - 512) / 2 / ANALOG_SENSITIVITY); + input.analog[i][1] = (int)((ir.sy - 384) * 2 / 3 / ANALOG_SENSITIVITY); + } + } + + /* USB mouse support */ + if (MOUSE_IsConnected()) + { + /* read mouse data */ + mouse_event event; + MOUSE_GetEvent(&event); + MOUSE_FlushEvents(); + + /* mouse position (-127;+127) -> (-255;+255) */ + input.analog[i][0] = event.rx * 2; + input.analog[i][1] = event.ry * 2; + + /* mouse buttons */ + if (event.button & 1) input.pad[i] |= INPUT_MOUSE_RIGHT; + if (event.button & 2) input.pad[i] |= INPUT_MOUSE_CENTER; + if (event.button & 4) input.pad[i] |= INPUT_MOUSE_LEFT; + } + + /* Y-Axis inversion */ + if (config.invert_mouse) + { + input.analog[i][1] = -input.analog[i][1]; + } + + /* Buttons */ + if (p & wpad_keymap[KEY_BUTTONA]) input.pad[i] |= INPUT_MOUSE_CENTER; + if (p & wpad_keymap[KEY_BUTTONB]) input.pad[i] |= INPUT_MOUSE_LEFT; + if (p & wpad_keymap[KEY_BUTTONC]) input.pad[i] |= INPUT_MOUSE_RIGHT; + if (p & wpad_keymap[KEY_START]) input.pad[i] |= INPUT_START; + + break; + } + + case DEVICE_PICO: + { + /* D-PAD */ + if (p & PAD_BUTTON_UP) input.pad[i] |= INPUT_UP; + else if (p & PAD_BUTTON_DOWN) input.pad[i] |= INPUT_DOWN; + if (p & PAD_BUTTON_LEFT) input.pad[i] |= INPUT_LEFT; + else if (p & PAD_BUTTON_RIGHT) input.pad[i] |= INPUT_RIGHT; + + /* PEN screen position (x,y) */ + input.analog[0][0] += x / ANALOG_SENSITIVITY; + input.analog[0][1] -= y / ANALOG_SENSITIVITY; + + /* Limits */ + if (input.analog[0][0] < 0x17c) input.analog[0][0] = 0x17c; + else if (input.analog[0][0] > 0x3c) input.analog[0][0] = 0x3c; + if (input.analog[0][1] < 0x1fc) input.analog[0][1] = 0x1fc; + else if (input.analog[0][1] > 0x3f3) input.analog[0][1] = 0x3f3; + + /* Wiimote IR */ + if (exp != WPAD_EXP_CLASSIC) + { + struct ir_t ir; + WPAD_IR(chan, &ir); + if (ir.valid) + { + input.analog[0][0] = 0x3c + (ir.x * (0x17c - 0x3c + 1)) / 640; + input.analog[0][1] = 0x1fc + (ir.y * (0x3f3 - 0x1fc + 1)) / 480; + } + } + + /* PEN button */ + if (p & wpad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_PICO_PEN; + + /* RED button */ + if (p & wpad_keymap[KEY_BUTTONB]) input.pad[0] |= INPUT_PICO_RED; + + /* PAGE index increment */ + if (p & wpad_keymap[KEY_BUTTONC]) pico_current = (pico_current + 1) & 7; + + break; + } + + case DEVICE_TEREBI: + { + /* PEN screen position (x,y) */ + input.analog[0][0] += x / ANALOG_SENSITIVITY; + input.analog[0][1] -= y / ANALOG_SENSITIVITY; + + /* Limits */ + if (input.analog[0][0] < 0) input.analog[0][0] = 0; + else if (input.analog[0][0] > 250) input.analog[0][0] = 250; + if (input.analog[0][1] < 0) input.analog[0][1] = 0; + else if (input.analog[0][1] > 250) input.analog[0][1] = 250; + + /* Wiimote IR */ + if (exp != WPAD_EXP_CLASSIC) + { + struct ir_t ir; + WPAD_IR(chan, &ir); + if (ir.valid) + { + input.analog[0][0] = (ir.x * 250) / 640; + input.analog[0][1] = (ir.y * 250) / 480; + } + } + + /* PEN button */ + if (p & wpad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_BUTTON1; + + break; + } + + case DEVICE_ACTIVATOR: + { + /* Classic Controller only */ + if (exp == WPAD_EXP_CLASSIC) + { + /* Left stick */ + float mag = data->exp.classic.ljs.mag; + float ang = data->exp.classic.ljs.ang; + + if (mag > 0.5) + { + /* 8 bottom sensors = 8 areas */ + if ((ang > 22.5) && (ang <= 67.5)) input.pad[i] |= INPUT_ACTIVATOR_2L; + else if ((ang > 67.5) && (ang <= 112.5)) input.pad[i] |= INPUT_ACTIVATOR_3L; + else if ((ang > 112.5) && (ang <= 157.5)) input.pad[i] |= INPUT_ACTIVATOR_4L; + else if ((ang > 157.5) && (ang <= 202.5)) input.pad[i] |= INPUT_ACTIVATOR_5L; + else if ((ang > 202.5) && (ang <= 247.5)) input.pad[i] |= INPUT_ACTIVATOR_6L; + else if ((ang > 247.5) && (ang <= 292.5)) input.pad[i] |= INPUT_ACTIVATOR_7L; + else if ((ang > 292.5) && (ang <= 337.5)) input.pad[i] |= INPUT_ACTIVATOR_8L; + else input.pad[i] |= INPUT_ACTIVATOR_1L; + } + + /* Right stick */ + mag = data->exp.classic.rjs.mag; + ang = data->exp.classic.rjs.ang; + + if (mag > 0.5) + { + /* 8 top sensors = 8 areas */ + if ((ang > 22.5) && (ang <= 67.5)) input.pad[i] |= INPUT_ACTIVATOR_2U; + else if ((ang > 67.5) && (ang <= 112.5)) input.pad[i] |= INPUT_ACTIVATOR_3U; + else if ((ang > 112.5) && (ang <= 157.5)) input.pad[i] |= INPUT_ACTIVATOR_4U; + else if ((ang > 157.5) && (ang <= 202.5)) input.pad[i] |= INPUT_ACTIVATOR_5U; + else if ((ang > 202.5) && (ang <= 247.5)) input.pad[i] |= INPUT_ACTIVATOR_6U; + else if ((ang > 247.5) && (ang <= 292.5)) input.pad[i] |= INPUT_ACTIVATOR_7U; + else if ((ang > 292.5) && (ang <= 337.5)) input.pad[i] |= INPUT_ACTIVATOR_8U; + else input.pad[i] |= INPUT_ACTIVATOR_1U; + } + } + + break; + } + } +} +#endif + + +/***************************************************************************************/ +/* GX Input interface */ +/***************************************************************************************/ +void gx_input_Init(void) +{ + PAD_Init(); +#ifdef HW_RVL + WPAD_Init(); + WPAD_SetIdleTimeout(60); + WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); + WPAD_SetVRes(WPAD_CHAN_ALL,640,480); +#endif +} + +int gx_input_FindDevices(void) +{ + int i; +#ifdef HW_RVL + u32 wpad; +#endif + int found = 0; + int player = 0; + + VIDEO_WaitVSync(); + u32 pad = PAD_ScanPads(); + + for (i=0; i 0) + { + wpad_update(config.input[player].port, i, config.input[player].device - 1); + } +#endif + + /* increment player index */ + player ++; + } + } + + /* Update RAM patches */ + RAMCheatUpdate(); +} + +/* Menu inputs update function */ +void gx_input_UpdateMenu(void) +{ + /* Check if inputs update are disabled */ + if (inputs_disabled) return; + + /* PAD status update */ + PAD_ScanPads(); + + /* PAD pressed keys */ + s16 pp = PAD_ButtonsDown(0); + + /* PAD held keys (direction/selection) */ + s16 hp = PAD_ButtonsHeld(0) & PAD_BUTTONS_HELD; + + /* PAD analog sticks (handled as PAD held direction keys) */ + s8 x = PAD_StickX(0); + s8 y = PAD_StickY(0); + if (x > ANALOG_SENSITIVITY) hp |= PAD_BUTTON_RIGHT; + else if (x < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_LEFT; + else if (y > ANALOG_SENSITIVITY) hp |= PAD_BUTTON_UP; + else if (y < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_DOWN; + +#ifdef HW_RVL + /* WPAD status update */ + WPAD_ScanPads(); + WPADData *data = WPAD_Data(0); + + /* WPAD pressed keys */ + u32 pw = data->btns_d; + + /* WPAD held keys (direction/selection) */ + u32 hw = data->btns_h & WPAD_BUTTONS_HELD; + + /* WPAD analog sticks (handled as PAD held direction keys) */ + x = wpad_StickX(data, 0); + y = wpad_StickY(data, 0); + if (x > ANALOG_SENSITIVITY) hp |= PAD_BUTTON_RIGHT; + else if (x < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_LEFT; + else if (y > ANALOG_SENSITIVITY) hp |= PAD_BUTTON_UP; + else if (y < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_DOWN; +#endif + + /* check if any direction/selection key is being held or just being pressed/released */ +#ifdef HW_RVL + if (pp||pw) held_cnt = 0; + else if (hp||hw) held_cnt++; + else held_cnt = 0; +#else + if (pp) held_cnt = 0; + else if (hp) held_cnt++; + else held_cnt = 0; +#endif + + /* initial delay (prevents triggering to start immediately) */ + if (held_cnt > HELD_DELAY) + { + /* key triggering */ + pp |= hp; +#ifdef HW_RVL + pw |= hw; +#endif + + /* delay until next triggering (adjusts direction/selection update speed) */ + held_cnt -= HELD_SPEED; + } + +#ifdef HW_RVL + /* Wiimote direction keys */ + WPAD_IR(0, &m_input.ir); + if (m_input.ir.valid) + { + /* Wiimote is handled vertically */ + if (pw & WPAD_BUTTON_UP) pp |= PAD_BUTTON_UP; + else if (pw & WPAD_BUTTON_DOWN) pp |= PAD_BUTTON_DOWN; + else if (pw & WPAD_BUTTON_LEFT) pp |= PAD_BUTTON_LEFT; + else if (pw & WPAD_BUTTON_RIGHT) pp |= PAD_BUTTON_RIGHT; + } + else + { + /* Wiimote is handled horizontally */ + if (pw & WPAD_BUTTON_UP) pp |= PAD_BUTTON_LEFT; + else if (pw & WPAD_BUTTON_DOWN) pp |= PAD_BUTTON_RIGHT; + else if (pw & WPAD_BUTTON_LEFT) pp |= PAD_BUTTON_DOWN; + else if (pw & WPAD_BUTTON_RIGHT) pp |= PAD_BUTTON_UP; + } + + /* Classic Controller direction keys */ + if (pw & WPAD_CLASSIC_BUTTON_UP) pp |= PAD_BUTTON_UP; + else if (pw & WPAD_CLASSIC_BUTTON_DOWN) pp |= PAD_BUTTON_DOWN; + else if (pw & WPAD_CLASSIC_BUTTON_LEFT) pp |= PAD_BUTTON_LEFT; + else if (pw & WPAD_CLASSIC_BUTTON_RIGHT) pp |= PAD_BUTTON_RIGHT; + + /* WPAD buttons */ + if (pw & WPAD_BUTTON_A) pp |= PAD_BUTTON_A; + if (pw & WPAD_BUTTON_B) pp |= PAD_BUTTON_B; + if (pw & WPAD_BUTTON_2) pp |= PAD_BUTTON_A; + if (pw & WPAD_BUTTON_1) pp |= PAD_BUTTON_B; + if (pw & WPAD_BUTTON_HOME) pp |= PAD_TRIGGER_Z; + if (pw & WPAD_BUTTON_PLUS) pp |= PAD_TRIGGER_L; + if (pw & WPAD_BUTTON_MINUS) pp |= PAD_TRIGGER_R; + if (pw & WPAD_CLASSIC_BUTTON_FULL_L) pp |= PAD_TRIGGER_L; + if (pw & WPAD_CLASSIC_BUTTON_FULL_R) pp |= PAD_TRIGGER_R; + if (pw & WPAD_CLASSIC_BUTTON_A) pp |= PAD_BUTTON_A; + if (pw & WPAD_CLASSIC_BUTTON_B) pp |= PAD_BUTTON_B; + if (pw & WPAD_CLASSIC_BUTTON_HOME) pp |= PAD_TRIGGER_Z; +#endif + + /* Update menu inputs */ + m_input.keys = pp; +} diff --git a/genplus-gx/gx/gx_input.h b/genplus-gx/gx/gx_input.h new file mode 100644 index 0000000000..77143b465e --- /dev/null +++ b/genplus-gx/gx/gx_input.h @@ -0,0 +1,72 @@ +/**************************************************************************** + * gx_input.c + * + * Genesis Plus GX input support + * + * Copyright Eke-Eke (2007-2013) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _GC_INPUT_H_ +#define _GC_INPUT_H_ + +#define osd_input_update() gx_input_UpdateEmu() + +/* max. supported inputs */ +#ifdef HW_RVL +#define MAX_INPUTS 8 +#else +#define MAX_INPUTS 4 +#endif + +/* Configurable keys */ +#define MAX_KEYS 8 + + +/* Key configuration structure */ +typedef struct +{ + s8 device; + u8 port; + u8 padtype; +} t_input_config; + + +extern void gx_input_Init(void); +extern int gx_input_FindDevices(void); +extern void gx_input_SetDefault(void); +extern void gx_input_Config(u8 chan, u8 device, u8 type); +extern void gx_input_UpdateEmu(void); +extern void gx_input_UpdateMenu(void); + +#endif diff --git a/genplus-gx/gx/gx_video.c b/genplus-gx/gx/gx_video.c new file mode 100644 index 0000000000..5521b238df --- /dev/null +++ b/genplus-gx/gx/gx_video.c @@ -0,0 +1,2041 @@ +/**************************************************************************** + * gx_video.c + * + * Genesis Plus GX video & rendering support + * + * Copyright Eke-Eke (2007-2013), based on original work from Softdev (2006) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "font.h" +#include "md_ntsc.h" +#include "sms_ntsc.h" +#include "gx_input.h" + +#include +#include + +#define TEX_WIDTH 720 +#define TEX_HEIGHT 576 +#define TEX_SIZE (TEX_WIDTH * TEX_HEIGHT * 2) +#define DEFAULT_FIFO_SIZE 256 * 1024 +#define HASPECT 320 +#define VASPECT 240 + +/* libpng wrapper */ +typedef struct +{ + u8 *buffer; + u32 offset; +} png_image; + +extern const u8 Crosshair_p1_png[]; +extern const u8 Crosshair_p2_png[]; +extern const u8 CD_access_off_png[]; +extern const u8 CD_access_on_png[]; +extern const u8 CD_ready_off_png[]; +extern const u8 CD_ready_on_png[]; + +/*** VI ***/ +GXRModeObj *vmode; /* Default Video Mode */ +u8 *texturemem; /* Texture Data */ +u8 *screenshot; /* Texture Data */ + +/*** 50/60hz flag ***/ +u32 gc_pal; + +/*** NTSC Filters ***/ +sms_ntsc_t *sms_ntsc; +md_ntsc_t *md_ntsc; + +/*** GX FIFO ***/ +static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32); + +/*** GX Textures ***/ +static u32 vwidth, vheight; +static gx_texture *crosshair[2]; +static gx_texture *cd_leds[2][2]; + +/*** Framebuffers ***/ +static u32 *xfb[2]; +static u32 whichfb = 0; + +/*** Frame Sync ***/ +u32 videoSync; +static u32 videoWait; +static u32 frameCount; +static u64 starttime; + +/*** OSD ***/ +static u32 osd; +static char msg[16]; + +/***************************************************************************************/ +/* Emulation video modes */ +/***************************************************************************************/ +static GXRModeObj *rmode; + +/* 288 lines progressive (PAL 50Hz) */ +static GXRModeObj TV50hz_288p = +{ + VI_TVMODE_PAL_DS, // viDisplayMode + 640, // fbWidth + VI_MAX_HEIGHT_PAL/2, // efbHeight + VI_MAX_HEIGHT_PAL/2, // xfbHeight + 0, // viXOrigin + 0, // viYOrigin + VI_MAX_WIDTH_PAL, // viWidth + VI_MAX_HEIGHT_PAL, // viHeight + VI_XFBMODE_SF, // xFBmode + GX_FALSE, // field_rendering + GX_FALSE, // aa + + // sample points arranged in increasing Y order + { + {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each + {6,6},{6,6},{6,6}, // pix 1 + {6,6},{6,6},{6,6}, // pix 2 + {6,6},{6,6},{6,6} // pix 3 + }, + + // vertical filter[7], 1/64 units, 6 bits each + { + 0, // line n-1 + 0, // line n-1 + 21, // line n + 22, // line n + 21, // line n + 0, // line n+1 + 0 // line n+1 + } +}; + +/* 288 lines interlaced (PAL 50Hz) */ +static GXRModeObj TV50hz_288i = +{ + VI_TVMODE_PAL_INT, // viDisplayMode + 640, // fbWidth + VI_MAX_HEIGHT_PAL/2, // efbHeight + VI_MAX_HEIGHT_PAL/2, // xfbHeight + 0, // viXOrigin + 0, // viYOrigin + VI_MAX_WIDTH_PAL, // viWidth + VI_MAX_HEIGHT_PAL, // viHeight + VI_XFBMODE_SF, // xFBmode + GX_TRUE, // field_rendering + GX_FALSE, // aa + + // sample points arranged in increasing Y order + { + {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each + {6,6},{6,6},{6,6}, // pix 1 + {6,6},{6,6},{6,6}, // pix 2 + {6,6},{6,6},{6,6} // pix 3 + }, + + // vertical filter[7], 1/64 units, 6 bits each + { + 0, // line n-1 + 0, // line n-1 + 21, // line n + 22, // line n + 21, // line n + 0, // line n+1 + 0 // line n+1 + } +}; + +/* 576 lines interlaced (PAL 50Hz, scaled) */ +static GXRModeObj TV50hz_576i = +{ + VI_TVMODE_PAL_INT, // viDisplayMode + 640, // fbWidth + 480, // efbHeight + VI_MAX_HEIGHT_PAL, // xfbHeight + 0, // viXOrigin + 0, // viYOrigin + VI_MAX_WIDTH_PAL, // viWidth + VI_MAX_HEIGHT_PAL, // viHeight + VI_XFBMODE_DF, // xFBmode + GX_FALSE, // field_rendering + GX_FALSE, // aa + + // sample points arranged in increasing Y order + { + {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each + {6,6},{6,6},{6,6}, // pix 1 + {6,6},{6,6},{6,6}, // pix 2 + {6,6},{6,6},{6,6} // pix 3 + }, + + // vertical filter[7], 1/64 units, 6 bits each + { + 8, // line n-1 + 8, // line n-1 + 10, // line n + 12, // line n + 10, // line n + 8, // line n+1 + 8 // line n+1 + } +}; + +/* 240 lines progressive (NTSC or PAL 60Hz) */ +static GXRModeObj TV60hz_240p = +{ + VI_TVMODE_EURGB60_DS, // viDisplayMode + 640, // fbWidth + VI_MAX_HEIGHT_NTSC/2, // efbHeight + VI_MAX_HEIGHT_NTSC/2, // xfbHeight + 0, // viXOrigin + 0, // viYOrigin + VI_MAX_WIDTH_NTSC, // viWidth + VI_MAX_HEIGHT_NTSC, // viHeight + VI_XFBMODE_SF, // xFBmode + GX_FALSE, // field_rendering + GX_FALSE, // aa + + // sample points arranged in increasing Y order + { + {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each + {6,6},{6,6},{6,6}, // pix 1 + {6,6},{6,6},{6,6}, // pix 2 + {6,6},{6,6},{6,6} // pix 3 + }, + + // vertical filter[7], 1/64 units, 6 bits each + { + 0, // line n-1 + 0, // line n-1 + 21, // line n + 22, // line n + 21, // line n + 0, // line n+1 + 0 // line n+1 + } +}; + +/* 240 lines interlaced (NTSC or PAL 60Hz) */ +static GXRModeObj TV60hz_240i = +{ + VI_TVMODE_EURGB60_INT, // viDisplayMode + 640, // fbWidth + VI_MAX_HEIGHT_NTSC/2, // efbHeight + VI_MAX_HEIGHT_NTSC/2, // xfbHeight + 0, // viXOrigin + 0, // viYOrigin + VI_MAX_WIDTH_NTSC, // viWidth + VI_MAX_HEIGHT_NTSC, // viHeight + VI_XFBMODE_SF, // xFBmode + GX_TRUE, // field_rendering + GX_FALSE, // aa + + // sample points arranged in increasing Y order + { + {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each + {3,2},{9,6},{3,10}, // pix 1 + {9,2},{3,6},{9,10}, // pix 2 + {9,2},{3,6},{9,10} // pix 3 + }, + + // vertical filter[7], 1/64 units, 6 bits each + { + 0, // line n-1 + 0, // line n-1 + 21, // line n + 22, // line n + 21, // line n + 0, // line n+1 + 0 // line n+1 + } +}; + +/* 480 lines interlaced (NTSC or PAL 60Hz) */ +static GXRModeObj TV60hz_480i = +{ + VI_TVMODE_EURGB60_INT,// viDisplayMode + 640, // fbWidth + VI_MAX_HEIGHT_NTSC, // efbHeight + VI_MAX_HEIGHT_NTSC, // xfbHeight + 0, // viXOrigin + 0, // viYOrigin + VI_MAX_WIDTH_NTSC, // viWidth + VI_MAX_HEIGHT_NTSC, // viHeight + VI_XFBMODE_DF, // xFBmode + GX_FALSE, // field_rendering + GX_FALSE, // aa + + // sample points arranged in increasing Y order + { + {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each + {6,6},{6,6},{6,6}, // pix 1 + {6,6},{6,6},{6,6}, // pix 2 + {6,6},{6,6},{6,6} // pix 3 + }, + + // vertical filter[7], 1/64 units, 6 bits each + { + 8, // line n-1 + 8, // line n-1 + 10, // line n + 12, // line n + 10, // line n + 8, // line n+1 + 8 // line n+1 + } +}; + +/* TV modes pointer table */ +static GXRModeObj *tvmodes[6] = +{ + /* 60hz modes */ + &TV60hz_240p, + &TV60hz_240i, + &TV60hz_480i, + + /* 50Hz modes */ + &TV50hz_288p, + &TV50hz_288i, + &TV50hz_576i +}; + +/***************************************************************************************/ +/* GX rendering engine */ +/***************************************************************************************/ + +typedef struct tagcamera +{ + guVector pos; + guVector up; + guVector view; +} camera; + +/*** Square Matrix + This structure controls the size of the image on the screen. + Think of the output as a -80 x 80 by -60 x 60 graph. +***/ +static s16 square[] ATTRIBUTE_ALIGN (32) = +{ + /* + * X, Y, Z + * Values set are for roughly 4:3 aspect + */ + -HASPECT, VASPECT, 0, // 0 + HASPECT, VASPECT, 0, // 1 + HASPECT, -VASPECT, 0, // 2 + -HASPECT, -VASPECT, 0, // 3 +}; + +static camera cam = { + {0.0F, 0.0F, -100.0F}, + {0.0F, -1.0F, 0.0F}, + {0.0F, 0.0F, 0.0F} +}; + +/*** GX Display List ***/ +static u8 d_list[32] ATTRIBUTE_ALIGN(32) = +{ + GX_QUADS | GX_VTXFMT0, /* textured quad rendering (Vertex Format 0) */ + 0x00, 0x04, /* one quad = 4x vertex */ + 0x03, 0x00, 0x00, 0x00, 0x00, /* top left corner */ + 0x02, 0x00, 0x01, 0x00, 0x00, /* top right corner */ + 0x01, 0x00, 0x01, 0x00, 0x01, /* bottom right corner */ + 0x00, 0x00, 0x00, 0x00, 0x01, /* bottom left corner */ + 0x00, 0x00, 0x00, 0x00, 0x00, /* padding */ + 0x00, 0x00, 0x00, 0x00 +}; + +/* VSYNC callback */ +static void vi_callback(u32 cnt) +{ + videoWait = 0; +} + +/* Initialize GX */ +static void gxStart(void) +{ + /*** Clear out FIFO area ***/ + memset(&gp_fifo, 0, DEFAULT_FIFO_SIZE); + + /*** GX default ***/ + GX_Init(&gp_fifo, DEFAULT_FIFO_SIZE); + GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); + GX_SetCullMode(GX_CULL_NONE); + GX_SetClipMode(GX_CLIP_DISABLE); + GX_SetDispCopyGamma(GX_GM_1_0); + GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); + GX_SetColorUpdate(GX_TRUE); + GX_SetAlphaUpdate(GX_FALSE); + + /* Modelview */ + Mtx view; + memset (&view, 0, sizeof (Mtx)); + guLookAt(view, &cam.pos, &cam.up, &cam.view); + GX_LoadPosMtxImm(view, GX_PNMTX0); + GX_Flush(); +} + +/* Reset GX rendering */ +static void gxResetRendering(u8 type) +{ + GX_ClearVtxDesc(); + + if (type) + { + /* uses direct positionning, alpha blending & color channel (menu rendering) */ + GX_SetBlendMode(GX_BM_BLEND,GX_BL_SRCALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); + GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GX_SetVtxDesc (GX_VA_CLR0, GX_DIRECT); + /* + Color.out = Color.rasterized*Color.texture + Alpha.out = Alpha.rasterized*Alpha.texture + */ + GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE); + GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GX_SetNumTexGens(1); + GX_SetNumChans(1); + } + else + { + /* uses array positionning, no alpha blending, no color channel (video emulation) */ + GX_SetBlendMode(GX_BM_NONE,GX_BL_SRCALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0); + GX_SetVtxDesc(GX_VA_POS, GX_INDEX8); + GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GX_SetArray(GX_VA_POS, square, 3 * sizeof (s16)); + /* + Color.out = Color.texture + Alpha.out = Alpha.texture + */ + GX_SetTevOp (GX_TEVSTAGE0, GX_REPLACE); + GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL); + GX_SetNumTexGens(1); + GX_SetNumChans(0); + } + + GX_Flush(); +} + +/* Reset GX rendering mode */ +static void gxResetMode(GXRModeObj *tvmode, int vfilter_enabled) +{ + Mtx44 p; + f32 yScale = GX_GetYScaleFactor(tvmode->efbHeight, tvmode->xfbHeight); + u16 xfbHeight = GX_SetDispCopyYScale(yScale); + u16 xfbWidth = VIDEO_PadFramebufferWidth(tvmode->fbWidth); + + GX_SetCopyClear((GXColor)BLACK,0x00ffffff); + GX_SetViewport(0.0F, 0.0F, tvmode->fbWidth, tvmode->efbHeight, 0.0F, 1.0F); + GX_SetScissor(0, 0, tvmode->fbWidth, tvmode->efbHeight); + GX_SetDispCopySrc(0, 0, tvmode->fbWidth, tvmode->efbHeight); + GX_SetDispCopyDst(xfbWidth, xfbHeight); + GX_SetCopyFilter(tvmode->aa, tvmode->sample_pattern, (tvmode->xfbMode == VI_XFBMODE_SF) ? GX_FALSE : vfilter_enabled, tvmode->vfilter); + GX_SetFieldMode(tvmode->field_rendering, ((tvmode->viHeight == 2 * tvmode->xfbHeight) ? GX_ENABLE : GX_DISABLE)); + guOrtho(p, tvmode->efbHeight/2, -(tvmode->efbHeight/2), -(tvmode->fbWidth/2), tvmode->fbWidth/2, 100, 1000); + GX_LoadProjectionMtx(p, GX_ORTHOGRAPHIC); + GX_Flush(); +} + +/* Update Aspect Ratio */ +static void gxSetAspectRatio(int *xscale, int *yscale) +{ + /* Vertical Scaling is disabled by default */ + *yscale = (bitmap.viewport.h + (2 * bitmap.viewport.y)) / 2; + + /* Original aspect ratio */ + if (config.aspect) + { + /* Adjust vertical scaling when input & output video heights are different */ + if (vdp_pal && (!gc_pal || config.render)) + { + *yscale = *yscale * VI_MAX_HEIGHT_NTSC / VI_MAX_HEIGHT_PAL; + } + else if (!vdp_pal && gc_pal && !config.render) + { + *yscale = *yscale * VI_MAX_HEIGHT_PAL / VI_MAX_HEIGHT_NTSC; + } + + /* Horizontal Scaling */ + /* Wii/Gamecube pixel clock = 13.5 Mhz */ + /* "H32" pixel clock = Master Clock / 10 = 5.3693175 Mhz (NTSC) or 5.3203424 (PAL) */ + /* "H40" pixel clock = Master Clock / 8 = 6,711646875 Mhz (NTSC) or 6,650428 Mhz (PAL) */ + if (config.overscan & 2) + { + /* Horizontal borders are emulated */ + if (reg[12] & 1) + { + /* 348 "H40" pixels = 348 * Wii/GC pixel clock / "H40" pixel clock = approx. 700 (NTSC) or 707 (PAL) Wii/GC pixels */ + *xscale = (system_clock == MCLOCK_NTSC) ? 350 : 354; + } + else + { + /* 284 "H32" pixels = 284 * Wii/GC pixel clock / "H40" pixel clock = approx. 714 (NTSC) or 721 (PAL) Wii/GC pixels */ + *xscale = (system_clock == MCLOCK_NTSC) ? 357 : 361; + } + } + else + { + /* Horizontal borders are simulated */ + if ((system_hw == SYSTEM_GG) && !config.gg_extra) + { + /* 160 "H32" pixels = 160 * Wii/GC pixel clock / "H32" pixel clock = approx. 403 Wii/GC pixels (NTSC only) */ + *xscale = 202; + } + else + { + /* 320 "H40" pixels = 256 "H32" pixels = 256 * Wii/GC pixel clock / "H32" pixel clock = approx. 644 (NTSC) or 650 (PAL) Wii/GC pixels */ + *xscale = (system_clock == MCLOCK_NTSC) ? 322 : 325; + } + } + + /* Aspect correction for widescreen TV */ + if (config.aspect & 2) + { + /* Keep 4:3 aspect ratio on 16:9 output */ + *xscale = (*xscale * 3) / 4; + } + } + + /* Manual aspect ratio */ + else + { + /* By default, disable horizontal scaling */ + *xscale = bitmap.viewport.w + (2 * bitmap.viewport.x); + + /* Keep original aspect ratio in H32 modes */ + if (!(reg[12] & 1)) + { + *xscale = (*xscale * 320) / 256; + } + + /* Game Gear specific: if borders are disabled, upscale to fullscreen */ + if ((system_hw == SYSTEM_GG) && !config.gg_extra) + { + if (!(config.overscan & 1)) + { + /* Active area height = approx. 224 non-interlaced lines (60hz) */ + *yscale = 112; + } + + if (!(config.overscan & 2)) + { + /* Active area width = approx. 640 pixels */ + *xscale = 320; + } + } + + /* By default, keep NTSC aspect ratio */ + if (gc_pal && !config.render) + { + /* Upscale PAL output */ + *yscale = *yscale * VI_MAX_HEIGHT_PAL / VI_MAX_HEIGHT_NTSC; + } + + /* Add user scaling */ + *xscale += config.xscale; + *yscale += config.yscale; + } +} + +/* Reset GX/VI hardware scaler */ +static void gxResetScaler(u32 width) +{ + int xscale = 0; + int yscale = 0; + int offset = 0; + + /* retrieve screen aspect ratio */ + gxSetAspectRatio(&xscale, &yscale); + + /* default EFB width */ + rmode->fbWidth = 640; + + /* no filtering, disable GX horizontal scaling */ + if (!config.bilinear && !config.ntsc) + { + if ((width <= 320) && (width <= xscale)) + rmode->fbWidth = width * 2; + else if (width <= 640) + rmode->fbWidth = width; + } + + /* configure VI width */ + if ((xscale * 2) > rmode->fbWidth) + { + /* max width = 720 pixels */ + if (xscale > 360) + { + /* save offset for later */ + offset = ((xscale - 360) * rmode->fbWidth) / rmode->viWidth; + + /* maximal width */ + xscale = 360; + } + + /* enable VI upscaling */ + rmode->viWidth = xscale * 2; + rmode->viXOrigin = (720 - (xscale * 2)) / 2; + + /* default GX horizontal scaling */ + xscale = (rmode->fbWidth / 2); + + /* handle additional upscaling */ + if (offset) + { + /* no filtering, reduce EFB width to increase VI upscaling */ + if (!config.bilinear && !config.ntsc) + rmode->fbWidth -= (offset * 2); + + /* increase GX horizontal scaling */ + else + xscale += offset; + } + } + else + { + /* VI horizontal scaling is disabled */ + rmode->viWidth = rmode->fbWidth; + rmode->viXOrigin = (720 - rmode->fbWidth) / 2; + } + + /* Adjust screen position */ + int xshift = (config.xshift * rmode->fbWidth) / rmode->viWidth; + int yshift = (config.yshift * rmode->efbHeight) / rmode->viHeight; + + /* Double Resolution modes (480i/576i/480p) */ + if (config.render) + { + yscale = yscale * 2; + } + + /* Set GX scaler (Vertex Position matrix) */ + square[6] = square[3] = xshift + xscale; + square[0] = square[9] = xshift - xscale; + square[4] = square[1] = yshift + yscale; + square[7] = square[10] = yshift - yscale; + DCFlushRange(square, 32); + GX_InvVtxCache(); +} + +static void gxDrawCrosshair(gx_texture *texture, int x, int y) +{ + /* adjust texture dimensions to XFB->VI scaling */ + int w = (texture->width * rmode->fbWidth) / (rmode->viWidth); + int h = (texture->height * rmode->efbHeight) / (rmode->viHeight); + + /* Aspect correction for widescreen TV */ + if (config.aspect & 2) w = (w * 3) / 4; + + /* EFB scale & shift */ + int xwidth = square[3] - square[9]; + int ywidth = square[4] - square[10]; + + /* adjust texture coordinates to EFB */ + x = (((x + bitmap.viewport.x) * xwidth) / vwidth) + square[9] - w/2; + y = (((y + bitmap.viewport.y) * ywidth) / vheight) + square[10] - h/2; + + /* load texture object */ + GXTexObj texObj; + GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GX_InitTexObjLOD(&texObj,GX_LINEAR,GX_LIN_MIP_LIN,0.0,10.0,0.0,GX_FALSE,GX_TRUE,GX_ANISO_4); + GX_LoadTexObj(&texObj, GX_TEXMAP0); + GX_InvalidateTexAll(); + + /* Draw textured quad */ + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position2s16(x,y+h); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(0.0, 1.0); + GX_Position2s16(x+w,y+h); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(1.0, 1.0); + GX_Position2s16(x+w,y); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(1.0, 0.0); + GX_Position2s16(x,y); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(0.0, 0.0); + GX_End(); +} + +static void gxDrawCdLeds(gx_texture *texture_l, gx_texture *texture_r) +{ + /* adjust texture dimensions to XFB->VI scaling */ + int w = (texture_l->width * rmode->fbWidth) / (rmode->viWidth); + int h = (texture_l->height * rmode->efbHeight) / (rmode->viHeight); + + /* Aspect correction for widescreen TV */ + if (config.aspect & 2) w = (w * 3) / 4; + + /* EFB scale & shift */ + int xwidth = square[3] - square[9]; + int ywidth = square[4] - square[10]; + + /* adjust texture coordinates to EFB */ + int xl = ((bitmap.viewport.x * xwidth) / vwidth) + square[9] + 8; + int xr = (((bitmap.viewport.x + bitmap.viewport.w) * xwidth) / vwidth) + square[9] - 8 - w; + int y = (((bitmap.viewport.y + bitmap.viewport.h - 4) * ywidth) / vheight) + square[10] - h; + + /* load left screen texture */ + GXTexObj texObj; + GX_InitTexObj(&texObj, texture_l->data, texture_l->width, texture_l->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GX_InitTexObjLOD(&texObj,GX_LINEAR,GX_LIN_MIP_LIN,0.0,10.0,0.0,GX_FALSE,GX_TRUE,GX_ANISO_4); + GX_LoadTexObj(&texObj, GX_TEXMAP0); + GX_InvalidateTexAll(); + + /* Draw textured quad */ + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position2s16(xl,y+h); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(0.0, 1.0); + GX_Position2s16(xl+w,y+h); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(1.0, 1.0); + GX_Position2s16(xl+w,y); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(1.0, 0.0); + GX_Position2s16(xl,y); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(0.0, 0.0); + GX_End(); + + /* load right screen texture */ + GX_InitTexObj(&texObj, texture_r->data, texture_r->width, texture_r->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GX_InitTexObjLOD(&texObj,GX_LINEAR,GX_LIN_MIP_LIN,0.0,10.0,0.0,GX_FALSE,GX_TRUE,GX_ANISO_4); + GX_LoadTexObj(&texObj, GX_TEXMAP0); + GX_InvalidateTexAll(); + + /* Draw textured quad */ + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position2s16(xr,y+h); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(0.0, 1.0); + GX_Position2s16(xr+w,y+h); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(1.0, 1.0); + GX_Position2s16(xr+w,y); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(1.0, 0.0); + GX_Position2s16(xr,y); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(0.0, 0.0); + GX_End(); +} + +static void gxDrawOnScreenText(char *msg) +{ + GXRModeObj *temp = vmode; + int y = (40 * rmode->efbHeight) / 480; + int x = (bitmap.viewport.x > 0) ? (24 + bitmap.viewport.x) : 24; + x = (x * rmode->fbWidth) / rmode->viWidth; + + vmode = rmode; + FONT_write(msg, 20, x, y, rmode->fbWidth, (GXColor)WHITE); + vmode = temp; +} + +void gxDrawRectangle(s32 x, s32 y, s32 w, s32 h, u8 alpha, GXColor color) +{ + /* GX only use Color channel for rendering */ + GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR); + GX_SetVtxDesc (GX_VA_TEX0, GX_NONE); + GX_Flush(); + + /* vertex coordinate */ + x -= (vmode->fbWidth/2); + y -= (vmode->efbHeight/2); + + /* draw colored quad */ + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position2s16(x,y+h); + GX_Color4u8(color.r,color.g,color.b,alpha); + GX_Position2s16(x+w,y+h); + GX_Color4u8(color.r,color.g,color.b,alpha); + GX_Position2s16(x+w,y); + GX_Color4u8(color.r,color.g,color.b,alpha); + GX_Position2s16(x,y); + GX_Color4u8(color.r,color.g,color.b,alpha); + GX_End(); + GX_DrawDone(); + + /* restore GX rendering */ + GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE); + GX_Flush(); +} + +void gxDrawTexture(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha) +{ + if (!texture) return; + if (texture->data) + { + /* load texture object */ + GXTexObj texObj; + GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GX_InitTexObjLOD(&texObj,GX_LINEAR,GX_LIN_MIP_LIN,0.0,10.0,0.0,GX_FALSE,GX_TRUE,GX_ANISO_4); /* does this really change anything ? */ + GX_LoadTexObj(&texObj, GX_TEXMAP0); + GX_InvalidateTexAll(); + + /* vertex coordinate */ + x -= (vmode->fbWidth/2); + y -= (vmode->efbHeight/2); + + /* draw textured quad */ + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position2s16(x,y+h); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(0.0, 1.0); + GX_Position2s16(x+w,y+h); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(1.0, 1.0); + GX_Position2s16(x+w,y); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(1.0, 0.0); + GX_Position2s16(x,y); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(0.0, 0.0); + GX_End(); + GX_DrawDone(); + } +} + +void gxDrawTextureRotate(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, f32 angle, u8 alpha) +{ + if (!texture) return; + if (texture->data) + { + /* load texture object */ + GXTexObj texObj; + GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GX_InitTexObjLOD(&texObj,GX_LINEAR,GX_LIN_MIP_LIN,0.0,10.0,0.0,GX_FALSE,GX_TRUE,GX_ANISO_4); + GX_LoadTexObj(&texObj, GX_TEXMAP0); + GX_InvalidateTexAll(); + + /* vertex coordinate */ + x -= (vmode->fbWidth/2); + y -= (vmode->efbHeight/2); + + /* Modelview rotation */ + Mtx m,mv; + guVector axis = (guVector) {0,0,1}; + guLookAt(mv, &cam.pos, &cam.up, &cam.view); + guMtxRotAxisDeg (m, &axis, angle); + guMtxTransApply(m,m, x+w/2,y+h/2,0); + guMtxConcat(mv,m,mv); + GX_LoadPosMtxImm(mv, GX_PNMTX0); + GX_Flush(); + + /* draw textured quad */ + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position2s16(-w/2,-h/2); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(0.0, 0.0); + GX_Position2s16(w/2,-h/2); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(1.0, 0.0); + GX_Position2s16(w/2,h/2); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(1.0, 1.0); + GX_Position2s16(-w/2,h/2); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(0.0, 1.0); + GX_End(); + GX_DrawDone(); + + /* restore default Modelview */ + guLookAt(mv, &cam.pos, &cam.up, &cam.view); + GX_LoadPosMtxImm(mv, GX_PNMTX0); + GX_Flush(); + } +} + +void gxDrawTextureRepeat(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha) +{ + if (!texture) return; + if (texture->data) + { + /* load texture object */ + GXTexObj texObj; + GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_REPEAT, GX_REPEAT, GX_FALSE); + GX_LoadTexObj(&texObj, GX_TEXMAP0); + GX_InvalidateTexAll(); + + /* vertex coordinate */ + x -= (vmode->fbWidth/2); + y -= (vmode->efbHeight/2); + + /* texture coordinates */ + f32 s = (f32)w / (f32)texture->width; + f32 t = (f32)h / (f32)texture->height; + + /* draw textured quad */ + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position2s16(x,y+h); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(0.0, t); + GX_Position2s16(x+w,y+h); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(s, t); + GX_Position2s16(x+w,y); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(s, 0.0); + GX_Position2s16(x,y); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(0.0, 0.0); + GX_End(); + GX_DrawDone(); + } +} + +void gxDrawScreenshot(u8 alpha) +{ + if (!rmode) return; + + /* get current game screen texture */ + GXTexObj texobj; + GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); + GX_LoadTexObj(&texobj, GX_TEXMAP0); + GX_InvalidateTexAll(); + + /* get current aspect ratio */ + int xscale,yscale; + gxSetAspectRatio(&xscale, &yscale); + + /* adjust horizontal scaling */ + xscale = (xscale * vmode->fbWidth) / vmode->viWidth; + + /* adjust screen position */ + int xshift = (config.xshift * vmode->fbWidth) / vmode->viWidth; + int yshift = (config.yshift * vmode->efbHeight) / vmode->viHeight; + + /* set vertices position & size */ + s32 x = xshift - xscale; + s32 y = yshift - (yscale * 2); + s32 w = xscale * 2; + s32 h = yscale * 4; + + /* black out surrounding area if necessary (Game Gear without borders) */ + if ((w < 640) || (h < 480)) + { + gxDrawRectangle(0, 0, 640, 480, 255, (GXColor)BLACK); + } + + /* draw textured quad */ + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position2s16(x,y+h); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(0.0, 1.0); + GX_Position2s16(x+w,y+h); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(1.0, 1.0); + GX_Position2s16(x+w,y); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(1.0, 0.0); + GX_Position2s16(x,y); + GX_Color4u8(0xff,0xff,0xff,alpha); + GX_TexCoord2f32(0.0, 0.0); + GX_End(); + GX_DrawDone(); +} + +void gxCopyScreenshot(gx_texture *texture) +{ + /* retrieve gamescreen texture */ + GXTexObj texobj; + GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); + GX_LoadTexObj(&texobj, GX_TEXMAP0); + GX_InvalidateTexAll(); + + /* scale texture to EFB width */ + s32 w = ((bitmap.viewport.w + 2*bitmap.viewport.x) * 640) / bitmap.viewport.w; + s32 h = (bitmap.viewport.h + 2*bitmap.viewport.y) * 2; + s32 x = -w/2; + s32 y = -(240+ 2*bitmap.viewport.y); + + /* black out surrounding area if necessary (Game Gear without borders) */ + if ((w < 640) || (h < 480)) + { + gxDrawRectangle(0, 0, 640, 480, 255, (GXColor)BLACK); + } + + /* draw textured quad */ + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position2s16(x,y+h); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(0.0, 1.0); + GX_Position2s16(x+w,y+h); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(1.0, 1.0); + GX_Position2s16(x+w,y); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(1.0, 0.0); + GX_Position2s16(x,y); + GX_Color4u8(0xff,0xff,0xff,0xff); + GX_TexCoord2f32(0.0, 0.0); + GX_End(); + + /* copy EFB to texture */ + texture->format = GX_TF_RGBA8; + texture->width = 320; + texture->height = bitmap.viewport.h; + texture->data = screenshot; + GX_SetTexCopySrc(0, 0, texture->width * 2, texture->height * 2); + GX_SetTexCopyDst(texture->width, texture->height, texture->format, GX_TRUE); + GX_DrawDone(); + GX_CopyTex(texture->data, GX_TRUE); + GX_Flush(); + + /* wait for copy operation to finish */ + /* GX_PixModeSync is only useful if GX_ command follows */ + /* we use dummy GX commands to stall CPU execution */ + GX_PixModeSync(); + GX_LoadTexObj(&texobj, GX_TEXMAP0); + GX_InvalidateTexAll(); + GX_Flush(); + DCFlushRange(texture->data, texture->width * texture->height * 4); +} + +/* Take Screenshot */ +void gxSaveScreenshot(char *filename) +{ + /* capture screenshot into a texture */ + gx_texture texture; + gxCopyScreenshot(&texture); + + /* open PNG file */ + FILE *f = fopen(filename,"wb"); + if (f) + { + /* encode screenshot into PNG file */ + gxTextureWritePNG(&texture,f); + fclose(f); + } +} + +void gxSetScreen(void) +{ + GX_DrawDone(); + GX_CopyDisp(xfb[whichfb], GX_FALSE); + GX_Flush(); + VIDEO_SetNextFramebuffer (xfb[whichfb]); + VIDEO_Flush (); + VIDEO_WaitVSync (); + gx_input_UpdateMenu(); +} + +void gxClearScreen(GXColor color) +{ + whichfb ^= 1; + GX_SetCopyClear(color,0x00ffffff); + GX_CopyDisp(xfb[whichfb], GX_TRUE); + GX_Flush(); +} + +/***************************************************************************************/ +/* GX Texture <-> LibPNG routines */ +/***************************************************************************************/ + +/* libpng read callback function */ +static void png_read_from_mem (png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_image *image = (png_image *)png_get_io_ptr(png_ptr); + + /* copy data from image buffer */ + memcpy (data, image->buffer + image->offset, length); + + /* advance in the file */ + image->offset += length; +} + +/* convert PNG image (from file or data buffer) into RGBA8 texture */ +gx_texture *gxTextureOpenPNG(const u8 *png_data, FILE *png_file) +{ + int i; + + /* create a png read struct */ + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); + if (!png_ptr) return NULL; + + /* create a png info struct */ + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr,NULL,NULL); + return NULL; + } + + if (png_data) + { + /* init PNG image structure */ + png_image image; + image.buffer = (u8 *) png_data; + image.offset = 0; + + /* set callback for the read function */ + png_set_read_fn(png_ptr,(png_voidp *)(&image),png_read_from_mem); + } + else if (png_file) + { + /* check for valid magic number */ + png_byte magic[8]; + if (fread (magic, 1, 8, png_file) != 8) + { + png_destroy_read_struct(&png_ptr,&info_ptr,NULL); + return NULL; + } + + if (png_sig_cmp (magic, 0, 8)) + { + png_destroy_read_struct(&png_ptr,&info_ptr,NULL); + return NULL; + } + + /* set IO callback for read function */ + png_init_io (png_ptr, png_file); + png_set_sig_bytes (png_ptr, 8); + } + else + { + png_destroy_read_struct(&png_ptr,&info_ptr,NULL); + return NULL; + } + + /* read png info */ + png_read_info(png_ptr,info_ptr); + + /* retrieve image information */ + u32 width = png_get_image_width(png_ptr,info_ptr); + u32 height = png_get_image_height(png_ptr,info_ptr); + u32 bit_depth = png_get_bit_depth(png_ptr,info_ptr); + u32 color_type = png_get_color_type(png_ptr,info_ptr); + + /* ensure PNG file is in the supported format */ + if (png_file) + { + /* support for RGBA8 textures ONLY !*/ + if ((color_type != PNG_COLOR_TYPE_RGB_ALPHA) || (bit_depth != 8)) + { + png_destroy_read_struct(&png_ptr, &info_ptr,NULL); + return NULL; + } + + /* 4x4 tiles are required */ + if ((width%4) || (height%4)) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return NULL; + } + } + + /* allocate memory to store raw image data */ + u32 stride = width << 2; + u8 *img_data = memalign (32, stride * height); + if (!img_data) + { + png_destroy_read_struct(&png_ptr,&info_ptr,NULL); + return NULL; + } + + /* allocate row pointer data */ + png_bytep *row_pointers = (png_bytep *)memalign (32, sizeof (png_bytep) * height); + if (!row_pointers) + { + free (img_data); + png_destroy_read_struct(&png_ptr,&info_ptr,NULL); + return NULL; + } + + /* store raw image data */ + for (i = 0; i < height; i++) + { + row_pointers[i] = img_data + (i * stride); + } + + /* decode image */ + png_read_image(png_ptr, row_pointers); + + /* finish decompression and release memory */ + png_read_end(png_ptr, NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + free(row_pointers); + + /* initialize texture */ + gx_texture *texture = (gx_texture *)memalign(32, sizeof(gx_texture)); + if (!texture) + { + free (img_data); + return NULL; + } + + /* initialize texture data */ + texture->data = memalign(32, stride * height); + if (!texture->data) + { + free (img_data); + free(texture); + return NULL; + } + + memset(texture->data, 0, stride * height); + texture->width = width; + texture->height = height; + texture->format = GX_TF_RGBA8; + + /* encode to GX_TF_RGBA8 format (4x4 pixels paired titles) */ + u16 *dst_ar = (u16 *)(texture->data); + u16 *dst_gb = (u16 *)(texture->data + 32); + u32 *src1 = (u32 *)(img_data); + u32 *src2 = (u32 *)(img_data + stride); + u32 *src3 = (u32 *)(img_data + 2*stride); + u32 *src4 = (u32 *)(img_data + 3*stride); + u32 pixel,h,w; + + for (h=0; h> 24) & 0x00ff); + *dst_gb++= (pixel >> 8) & 0xffff; + } + + /* line N + 1 (4 pixels) */ + for (i=0; i<4; i++) + { + pixel = *src2++; + *dst_ar++= ((pixel << 8) & 0xff00) | ((pixel >> 24) & 0x00ff); + *dst_gb++= (pixel >> 8) & 0xffff; + } + + /* line N + 2 (4 pixels) */ + for (i=0; i<4; i++) + { + pixel = *src3++; + *dst_ar++= ((pixel << 8) & 0xff00) | ((pixel >> 24) & 0x00ff); + *dst_gb++= (pixel >> 8) & 0xffff; + } + + /* line N + 3 (4 pixels) */ + for (i=0; i<4; i++) + { + pixel = *src4++; + *dst_ar++= ((pixel << 8) & 0xff00) | ((pixel >> 24) & 0x00ff); + *dst_gb++= (pixel >> 8) & 0xffff; + } + + /* next paired tiles */ + dst_ar += 16; + dst_gb += 16; + } + + /* next 4 lines */ + src1 = src4; + src2 = src1 + width; + src3 = src2 + width; + src4 = src3 + width; + } + + /* release memory */ + free(img_data); + + /* flush texture data from cache */ + DCFlushRange(texture->data, height * stride); + + return texture; +} + +/* Write RGBA8 Texture to PNG file */ +void gxTextureWritePNG(gx_texture *texture, FILE *png_file) +{ + /* allocate PNG data buffer */ + u8 *img_data = (u8 *)memalign(32, texture->width * texture->height * 4); + if(!img_data) return; + + /* decode GX_TF_RGBA8 format (4x4 pixels paired titles) */ + u16 *ar = (u16 *)(texture->data); + u16 *gb = (u16 *)(texture->data + 32); + u32 *dst1 = (u32 *)(img_data); + u32 *dst2 = dst1 + texture->width; + u32 *dst3 = dst2 + texture->width; + u32 *dst4 = dst3 + texture->width; + u32 i,h,w,pixel; + + for (h=0; hheight; h+=4) + { + for (w=0; wwidth; w+=4) + { + /* line N (4 pixels) */ + for (i=0; i<4; i++) + { + pixel = ((*ar & 0xff) << 24) | (*gb << 8) | ((*ar & 0xff00) >> 8); + *dst1++ = pixel; + ar++; + gb++; + } + + /* line N + 1 (4 pixels) */ + for (i=0; i<4; i++) + { + pixel = ((*ar & 0xff) << 24) | (*gb << 8) | ((*ar & 0xff00) >> 8); + *dst2++ = pixel; + ar++; + gb++; + } + + /* line N + 2 (4 pixels) */ + for (i=0; i<4; i++) + { + pixel = ((*ar & 0xff) << 24) | (*gb << 8) | ((*ar & 0xff00) >> 8); + *dst3++ = pixel; + ar++; + gb++; + } + + /* line N + 3 (4 pixels) */ + for (i=0; i<4; i++) + { + pixel = ((*ar & 0xff) << 24) | (*gb << 8) | ((*ar & 0xff00) >> 8); + *dst4++ = pixel; + ar++; + gb++; + } + + /* next paired tiles */ + ar += 16; + gb += 16; + } + + /* next 4 lines */ + dst1 = dst4; + dst2 = dst1 + texture->width; + dst3 = dst2 + texture->width; + dst4 = dst3 + texture->width; + } + + /* create a png write struct */ + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(!png_ptr) + { + free(img_data); + return; + } + + /* create a png info struct */ + png_infop info_ptr = png_create_info_struct (png_ptr); + if (!info_ptr) + { + free(img_data); + png_destroy_write_struct(&png_ptr, NULL); + return; + } + + /* set IO callback for the write function */ + png_init_io(png_ptr, png_file); + + /* set PNG file properties */ + png_set_IHDR(png_ptr, info_ptr, texture->width, texture->height, 8, PNG_COLOR_TYPE_RGB_ALPHA, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + /* allocate row pointer data */ + png_bytep *row_pointers = (png_bytep *)memalign (32, sizeof (png_bytep) * texture->height); + if (!row_pointers) + { + free (img_data); + png_destroy_write_struct(&png_ptr, &info_ptr); + return; + } + + /* store raw image data */ + for (i = 0; i < texture->height; i++) + { + row_pointers[i] = img_data + (i * texture->width * 4); + } + + /* configure libpng for image data */ + png_set_rows(png_ptr,info_ptr,row_pointers); + + /* write data to PNG file */ + png_write_png(png_ptr,info_ptr,PNG_TRANSFORM_IDENTITY,NULL); + + /* finish compression and release memory */ + png_write_end(png_ptr, NULL); + free(row_pointers); + free(img_data); + png_destroy_write_struct(&png_ptr, &info_ptr); +} + + +void gxTextureClose(gx_texture **p_texture) +{ + gx_texture *texture = *p_texture; + + if (texture) + { + if (texture->data) free(texture->data); + free(texture); + *p_texture = NULL; + } +} + + +/***************************************************************************************/ +/* VIDEO engine */ +/***************************************************************************************/ + +/* Emulation mode -> Menu mode */ +void gx_video_Stop(void) +{ + /* wait for next VBLANK */ + VIDEO_WaitVSync (); + + /* unallocate NTSC filters */ + if (sms_ntsc) free(sms_ntsc); + if (md_ntsc) free(md_ntsc); + sms_ntsc = NULL; + md_ntsc = NULL; + + /* lightgun textures */ + gxTextureClose(&crosshair[0]); + gxTextureClose(&crosshair[1]); + + /* CD leds textures */ + gxTextureClose(&cd_leds[0][0]); + gxTextureClose(&cd_leds[0][1]); + gxTextureClose(&cd_leds[1][0]); + gxTextureClose(&cd_leds[1][1]); + + /* GX menu rendering */ + gxResetRendering(1); + gxResetMode(vmode, GX_TRUE); + + /* render game snapshot */ + gxClearScreen((GXColor)BLACK); + gxDrawScreenshot(0xff); + + /* default VI settings */ + VIDEO_SetPostRetraceCallback(NULL); +#ifdef HW_RVL + VIDEO_SetTrapFilter(1); + VIDEO_SetGamma(VI_GM_1_0); +#endif + + /* adjust TV width */ + vmode->viWidth = config.screen_w; + vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth)/2; + VIDEO_Configure(vmode); + + /* wait for VSYNC */ + gxSetScreen(); +} + +/* Menu mode -> Emulation mode */ +void gx_video_Start(void) +{ +#ifdef HW_RVL + VIDEO_SetTrapFilter(config.trap); + VIDEO_SetGamma((int)(config.gamma * 10.0)); +#endif + + /* TV mode */ + if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) + { + /* 50 Hz */ + gc_pal = 1; + } + else + { + /* 60 Hz */ + gc_pal = 0; + } + + /* When VSYNC is set to AUTO & console TV mode matches emulated video mode, emulation is synchronized with video hardware as well */ + if (config.vsync && (gc_pal == vdp_pal)) + { + /* VSYNC callback */ + VIDEO_SetPostRetraceCallback(vi_callback); + VIDEO_Flush(); + videoSync = audioSync; + } + else + { + videoSync = 0; + } + + /* Enable progressive or interlaced video mode */ + if (config.render == 2) + { + /* 480p */ + tvmodes[2]->viTVMode = (tvmodes[2]->viTVMode & ~3) | VI_PROGRESSIVE; + tvmodes[2]->xfbMode = VI_XFBMODE_SF; + + /* 576p */ + tvmodes[5]->viTVMode = VI_TVMODE_PAL_PROG; + tvmodes[5]->xfbMode = VI_XFBMODE_SF; + } + else if (config.render == 1) + { + /* 480i */ + tvmodes[2]->viTVMode = (tvmodes[2]->viTVMode & ~3) | VI_INTERLACE; + tvmodes[2]->xfbMode = VI_XFBMODE_DF; + + /* 576i */ + tvmodes[5]->viTVMode = VI_TVMODE_PAL_INT; + tvmodes[5]->xfbMode = VI_XFBMODE_DF; + } + + /* update horizontal border width */ + if ((system_hw == SYSTEM_GG) && !config.gg_extra) + { + bitmap.viewport.x = (config.overscan & 2) ? 14 : -48; + } + else + { + bitmap.viewport.x = (config.overscan & 2) * 7; + } + + /* force viewport update */ + bitmap.viewport.changed = 3; + + /* NTSC filter */ + if (config.ntsc) + { + /* allocate filters */ + if (!sms_ntsc) + { + sms_ntsc = (sms_ntsc_t *)memalign(32,sizeof(sms_ntsc_t)); + } + if (!md_ntsc) + { + md_ntsc = (md_ntsc_t *)memalign(32,sizeof(md_ntsc_t)); + } + + /* setup filters default configuration */ + switch (config.ntsc) + { + case 1: + sms_ntsc_init(sms_ntsc, &sms_ntsc_composite); + md_ntsc_init(md_ntsc, &md_ntsc_composite); + break; + case 2: + sms_ntsc_init(sms_ntsc, &sms_ntsc_svideo); + md_ntsc_init(md_ntsc, &md_ntsc_svideo); + break; + case 3: + sms_ntsc_init(sms_ntsc, &sms_ntsc_rgb); + md_ntsc_init(md_ntsc, &md_ntsc_rgb); + break; + } + } + + /* on-screen display enable flag */ + osd = config.fps; + + /* clear any on-screen text */ + memset(msg, 0, sizeof(msg)); + + /* lightgun textures */ + int i, player = 0; + for (i=0; i= 0) + { + if ((i == 0) || ((i == 4) && (input.system[1] != SYSTEM_LIGHTPHASER))) + { + /* Lightgun #1 */ + if (config.gun_cursor[0]) + { + crosshair[0] = gxTextureOpenPNG(Crosshair_p1_png,0); + osd = 1; + } + } + else + { + /* Lightgun #2 */ + if (config.gun_cursor[1]) + { + crosshair[1] = gxTextureOpenPNG(Crosshair_p2_png,0); + osd = 1; + } + } + } + } + + /* Check for any emulated device */ + if (input.dev[i] != NO_DEVICE) + { + /* increment player index */ + player++; + } + } + + /* CD leds textures */ + if (system_hw == SYSTEM_MCD) + { + if (config.cd_leds) + { + cd_leds[0][0] = gxTextureOpenPNG(CD_access_off_png,0); + cd_leds[0][1] = gxTextureOpenPNG(CD_access_on_png,0); + cd_leds[1][0] = gxTextureOpenPNG(CD_ready_off_png,0); + cd_leds[1][1] = gxTextureOpenPNG(CD_ready_on_png,0); + osd = 1; + } + } + + /* GX emulation rendering */ + gxResetRendering(0); + + /* resynchronize emulation with VSYNC */ + VIDEO_WaitVSync(); + + /* restart frame sync */ + videoWait = 0; + frameCount = 0; + starttime = gettime(); +} + +/* GX render update */ +int gx_video_Update(u32 done) +{ + if (videoWait || done) return SYNC_WAIT; + + videoWait = videoSync; + + /* check if display has changed during frame */ + if (bitmap.viewport.changed & 1) + { + /* update texture size */ + vwidth = bitmap.viewport.w + (2 * bitmap.viewport.x); + vheight = bitmap.viewport.h + (2 * bitmap.viewport.y); + + /* interlaced mode */ + if (config.render && interlaced) + { + vheight = vheight << 1; + } + + /* ntsc filter */ + if (config.ntsc) + { + vwidth = (reg[12] & 1) ? MD_NTSC_OUT_WIDTH(vwidth) : SMS_NTSC_OUT_WIDTH(vwidth); + + /* texel width must remain multiple of 4 */ + vwidth = (vwidth >> 2) << 2; + } + + /* initialize texture object */ + GXTexObj texobj; + GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); + + /* configure texture filtering */ + if (!config.bilinear) + { + GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,0.0,10.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1); + } + + /* load texture object */ + GX_LoadTexObj(&texobj, GX_TEXMAP0); + + /* update rendering mode */ + if (config.render) + { + rmode = tvmodes[gc_pal*3 + 2]; + } + else + { + rmode = tvmodes[gc_pal*3 + interlaced]; + } + + /* update aspect ratio */ + gxResetScaler(vwidth); + + /* update GX rendering mode */ + gxResetMode(rmode, config.vfilter); + + /* update VI mode */ + VIDEO_Configure(rmode); + } + + /* texture is now directly mapped by the line renderer */ + + /* force texture cache update */ + DCFlushRange(texturemem, TEX_SIZE); + GX_InvalidateTexAll(); + + /* render textured quad */ + GX_CallDispList(d_list, 32); + + /* on-screen display */ + if (osd) + { + /* reset GX rendering */ + gxResetRendering(1); + + /* lightgun # 1 screen mark */ + if (crosshair[0]) + { + if (input.system[0] == SYSTEM_LIGHTPHASER) + { + gxDrawCrosshair(crosshair[0], input.analog[0][0],input.analog[0][1]); + } + else + { + gxDrawCrosshair(crosshair[0], input.analog[4][0],input.analog[4][1]); + } + } + + /* lightgun #2 screen mark */ + if (crosshair[1]) + { + if (input.system[1] == SYSTEM_LIGHTPHASER) + { + gxDrawCrosshair(crosshair[1], input.analog[4][0],input.analog[4][1]); + } + else + { + gxDrawCrosshair(crosshair[1], input.analog[5][0],input.analog[5][1]); + } + } + + /* CD LEDS */ + if (cd_leds[1][1]) + { + /* CD LEDS status */ + u8 mode = scd.regs[0x06 >> 1].byte.h; + gxDrawCdLeds(cd_leds[1][(mode >> 1) & 1], cd_leds[0][mode & 1]); + } + + /* FPS counter */ + if (config.fps) + { + u32 delta = diff_usec(starttime, gettime()); + frameCount++; + if (delta > 1000000) + { + sprintf(msg,"%3.2f FPS", (float)frameCount * 1000000.0 / (float)delta); + frameCount = 0; + starttime = gettime(); + } + + /* disable EFB alpha blending for text background */ + GX_SetBlendMode(GX_BM_NONE,GX_BL_SRCALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR); + GX_Flush(); + + gxDrawOnScreenText(msg); + } + + /* restore GX rendering */ + gxResetRendering(0); + + /* restore texture object */ + GXTexObj texobj; + GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); + if (!config.bilinear) + { + GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,0.0,10.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1); + } + GX_LoadTexObj(&texobj, GX_TEXMAP0); + GX_InvalidateTexAll(); + } + + /* swap XFB */ + whichfb ^= 1; + + /* copy EFB to XFB */ + GX_DrawDone(); + GX_CopyDisp(xfb[whichfb], GX_TRUE); + GX_Flush(); + + /* XFB is ready to be displayed */ + VIDEO_SetNextFramebuffer(xfb[whichfb]); + VIDEO_Flush(); + + if (bitmap.viewport.changed & 1) + { + /* clear update flags */ + bitmap.viewport.changed &= ~1; + + /* field synchronization */ + VIDEO_WaitVSync(); + if (rmode->viTVMode & VI_NON_INTERLACE) + { + VIDEO_WaitVSync(); + } + else while (VIDEO_GetNextField() != odd_frame) + { + VIDEO_WaitVSync(); + } + + /* Audio DMA need to be resynchronized with VSYNC */ + audioStarted = 0; + } + + return SYNC_VIDEO; +} + +/* Initialize VIDEO subsystem */ +void gx_video_Init(void) +{ + /* + * Before doing anything else under libogc, + * Call VIDEO_Init + */ + VIDEO_Init(); + + /* Get the current VIDEO mode then : + - set menu video mode (480p/576p/480i/576i) + - set emulator rendering 60hz TV modes (MPAL/NTSC/EURGB60) + */ + vmode = VIDEO_GetPreferredMode(NULL); + + /* Adjust display settings */ + switch (vmode->viTVMode >> 2) + { + case VI_PAL: /* 576 lines scaled (PAL 50Hz) */ + TV60hz_240p.viTVMode = VI_TVMODE_EURGB60_DS; + TV60hz_240i.viTVMode = VI_TVMODE_EURGB60_INT; + TV60hz_480i.viTVMode = VI_TVMODE_EURGB60_INT; + break; + + default: /* 480 lines (NTSC, MPAL or PAL 60Hz) */ + TV60hz_240p.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_NON_INTERLACE); + TV60hz_240i.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_INTERLACE); + TV60hz_480i.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_INTERLACE); + break; + } + + /* Configure VI */ + VIDEO_Configure (vmode); + + /* Configure the framebuffers (double-buffering) */ + xfb[0] = (u32 *) MEM_K0_TO_K1((u32 *) SYS_AllocateFramebuffer(&TV50hz_576i)); + xfb[1] = (u32 *) MEM_K0_TO_K1((u32 *) SYS_AllocateFramebuffer(&TV50hz_576i)); + + /* Define a console */ + console_init(xfb[0], 20, 64, 640, 574, 574 * 2); + + /* Clear framebuffers to black */ + VIDEO_ClearFrameBuffer(vmode, xfb[0], COLOR_BLACK); + VIDEO_ClearFrameBuffer(vmode, xfb[1], COLOR_BLACK); + + /* Set the framebuffer to be displayed at next VBlank */ + VIDEO_SetNextFramebuffer(xfb[0]); + + /* Enable Video Interface */ + VIDEO_SetBlack(FALSE); + + /* Update VIDEO settings for next VBlank */ + VIDEO_Flush(); + + /* Wait for VBlank */ + VIDEO_WaitVSync(); + VIDEO_WaitVSync(); + + /* Initialize GX */ + gxStart(); + gxResetRendering(1); + gxResetMode(vmode, GX_TRUE); + + /* initialize FONT */ + FONT_Init(); + + /* Initialize textures */ + texturemem = memalign(32, TEX_SIZE); + screenshot = memalign(32, HASPECT*VASPECT*4); +} + +void gx_video_Shutdown(void) +{ + if (texturemem) free(texturemem); + if (screenshot) free(screenshot); + FONT_Shutdown(); + VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK); + VIDEO_Flush(); + VIDEO_WaitVSync(); +} + +/* Custom NTSC blitters */ +typedef unsigned short sms_ntsc_out_t; +typedef unsigned short md_ntsc_out_t; + +void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input, + int in_width, int vline) +{ + int const chunk_count = in_width / sms_ntsc_in_chunk; + + /* handle extra 0, 1, or 2 pixels by placing them at beginning of row */ + int const in_extra = in_width - chunk_count * sms_ntsc_in_chunk; + unsigned const extra2 = (unsigned) -(in_extra >> 1 & 1); /* (unsigned) -1 = ~0 */ + unsigned const extra1 = (unsigned) -(in_extra & 1) | extra2; + + /* use palette entry 0 for unused pixels */ + SMS_NTSC_IN_T border = table[0]; + + SMS_NTSC_BEGIN_ROW( ntsc, border, + (SMS_NTSC_ADJ_IN( table[input[0]] )) & extra2, + (SMS_NTSC_ADJ_IN( table[input[extra2 & 1]] )) & extra1 ); + + /* directly fill the RGB565 texture */ + /* one tile is 32 byte = 4x4 pixels */ + /* tiles are stored continuously in texture memory */ + in_width = SMS_NTSC_OUT_WIDTH(in_width) / 4; + int offset = ((in_width * 32) * (vline / 4)) + ((vline & 3) * 8); + sms_ntsc_out_t* __restrict__ line_out = (sms_ntsc_out_t*)(texturemem + offset); + offset = 0; + + int n; + input += in_extra; + + for ( n = chunk_count; n; --n ) + { + /* order of input and output pixels must not be altered */ + SMS_NTSC_COLOR_IN( 0, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) ); + SMS_NTSC_RGB_OUT( 0, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + SMS_NTSC_RGB_OUT( 1, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + + SMS_NTSC_COLOR_IN( 1, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) ); + SMS_NTSC_RGB_OUT( 2, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + SMS_NTSC_RGB_OUT( 3, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + + SMS_NTSC_COLOR_IN( 2, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) ); + SMS_NTSC_RGB_OUT( 4, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + SMS_NTSC_RGB_OUT( 5, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + SMS_NTSC_RGB_OUT( 6, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + } + + /* finish final pixels */ + SMS_NTSC_COLOR_IN( 0, ntsc, border ); + SMS_NTSC_RGB_OUT( 0, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + SMS_NTSC_RGB_OUT( 1, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + + SMS_NTSC_COLOR_IN( 1, ntsc, border ); + SMS_NTSC_RGB_OUT( 2, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + SMS_NTSC_RGB_OUT( 3, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + + SMS_NTSC_COLOR_IN( 2, ntsc, border ); + SMS_NTSC_RGB_OUT( 4, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + SMS_NTSC_RGB_OUT( 5, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; + SMS_NTSC_RGB_OUT( 6, line_out[offset++] ); + if ((offset % 4) == 0) offset += 12; +} + +void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input, + int in_width, int vline) +{ + int const chunk_count = in_width / md_ntsc_in_chunk - 1; + + /* use palette entry 0 for unused pixels */ + MD_NTSC_IN_T border = table[0]; + + MD_NTSC_BEGIN_ROW( ntsc, border, + MD_NTSC_ADJ_IN( table[*input++] ), + MD_NTSC_ADJ_IN( table[*input++] ), + MD_NTSC_ADJ_IN( table[*input++] ) ); + + /* directly fill the RGB565 texture */ + /* one tile is 32 byte = 4x4 pixels */ + /* tiles are stored continuously in texture memory */ + in_width = MD_NTSC_OUT_WIDTH(in_width) >> 2; + int offset = ((in_width << 5) * (vline >> 2)) + ((vline & 3) * 8); + md_ntsc_out_t* __restrict__ line_out = (md_ntsc_out_t*)(texturemem + offset); + + int n; + + for ( n = chunk_count; n; --n ) + { + /* order of input and output pixels must not be altered */ + MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) ); + MD_NTSC_RGB_OUT( 0, *line_out++ ); + MD_NTSC_RGB_OUT( 1, *line_out++ ); + + MD_NTSC_COLOR_IN( 1, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) ); + MD_NTSC_RGB_OUT( 2, *line_out++ ); + MD_NTSC_RGB_OUT( 3, *line_out++ ); + + line_out += 12; + + MD_NTSC_COLOR_IN( 2, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) ); + MD_NTSC_RGB_OUT( 4, *line_out++ ); + MD_NTSC_RGB_OUT( 5, *line_out++ ); + + MD_NTSC_COLOR_IN( 3, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) ); + MD_NTSC_RGB_OUT( 6, *line_out++ ); + MD_NTSC_RGB_OUT( 7, *line_out++ ); + + line_out += 12; +} + + /* finish final pixels */ + MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) ); + MD_NTSC_RGB_OUT( 0, *line_out++ ); + MD_NTSC_RGB_OUT( 1, *line_out++ ); + + MD_NTSC_COLOR_IN( 1, ntsc, border ); + MD_NTSC_RGB_OUT( 2, *line_out++ ); + MD_NTSC_RGB_OUT( 3, *line_out++ ); + + line_out += 12; + + MD_NTSC_COLOR_IN( 2, ntsc, border ); + MD_NTSC_RGB_OUT( 4, *line_out++ ); + MD_NTSC_RGB_OUT( 5, *line_out++ ); + + MD_NTSC_COLOR_IN( 3, ntsc, border ); + MD_NTSC_RGB_OUT( 6, *line_out++ ); + MD_NTSC_RGB_OUT( 7, *line_out++ ); +} diff --git a/genplus-gx/gx/gx_video.h b/genplus-gx/gx/gx_video.h new file mode 100644 index 0000000000..d069bffbdd --- /dev/null +++ b/genplus-gx/gx/gx_video.h @@ -0,0 +1,105 @@ +/**************************************************************************** + * gx_video.c + * + * Genesis Plus GX video support + * + * Copyright Eke-Eke (2007-2013), based on original work from Softdev (2006) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _GC_VIDEO_H_ +#define _GC_VIDEO_H_ + +/* EFB colors */ +#define BLACK {0x00,0x00,0x00,0xff} +#define DARK_GREY {0x22,0x22,0x22,0xff} +#define LIGHT_BLUE {0xb8,0xc7,0xda,0xff} +#define SKY_BLUE {0x99,0xcc,0xff,0xff} +#define LIGHT_GREEN {0xa9,0xc7,0xc6,0xff} +#define WHITE {0xff,0xff,0xff,0xff} + +/* Directly fill a RGB565 texture */ +/* One tile is 32 byte = 4x4 pixels */ +/* Tiles are stored continuously in texture memory */ +#define CUSTOM_BLITTER(line, width, table, in) \ + width >>= 2; \ + u16 *out = (u16 *) (texturemem + (((width << 5) * (line >> 2)) + ((line & 3) << 3))); \ + do \ + { \ + *out++ = table[*in++]; \ + *out++ = table[*in++]; \ + *out++ = table[*in++]; \ + *out++ = table[*in++]; \ + out += 12; \ + } \ + while (--width); + +/* image texture */ +typedef struct +{ + u8 *data; + u16 width; + u16 height; + u8 format; +} gx_texture; + +/* Global variables */ +extern GXRModeObj *vmode; +extern u8 *texturemem; +extern u32 gc_pal; +extern u32 videoSync; + +/* GX rendering */ +extern void gxDrawRectangle(s32 x, s32 y, s32 w, s32 h, u8 alpha, GXColor color); +extern void gxDrawTexture(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha); +extern void gxDrawTextureRepeat(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha); +extern void gxDrawTextureRotate(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, f32 angle, u8 alpha); +extern void gxDrawScreenshot(u8 alpha); +extern void gxCopyScreenshot(gx_texture *texture); +extern void gxSaveScreenshot(char *filename); +extern void gxClearScreen(GXColor color); +extern void gxSetScreen(void); + +/* PNG textures */ +extern gx_texture *gxTextureOpenPNG(const u8 *png_data, FILE *png_file); +extern void gxTextureWritePNG(gx_texture *p_texture, FILE *png_file); +extern void gxTextureClose(gx_texture **p_texture); + +/* GX video engine */ +extern void gx_video_Init(void); +extern void gx_video_Shutdown(void); +extern void gx_video_Start(void); +extern void gx_video_Stop(void); +extern int gx_video_Update(u32 done); + +#endif diff --git a/genplus-gx/gx/images/Banner_bottom.png b/genplus-gx/gx/images/Banner_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..85545b1a1627eebffceb840d9ad00dc859214eac GIT binary patch literal 4704 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Banner_main.png b/genplus-gx/gx/images/Banner_main.png new file mode 100644 index 0000000000000000000000000000000000000000..ee11383b8e95c278300c3c5b8a2915a044db9eb9 GIT binary patch literal 23123 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Banner_top.png b/genplus-gx/gx/images/Banner_top.png new file mode 100644 index 0000000000000000000000000000000000000000..1ac9b04316aac2c07852dd0975c472f5f137b156 GIT binary patch literal 6169 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

>j$ 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 K7gZj8k~-k6{&1d%kU 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�nE=!MiRRsnGOjifF#$3YJm%M5sA8R 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

@m4jB}J{v20>zS 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._Y`k$XpS5V`G(kJw`f{kZLEuy*oWdj*zmENfe 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Bg_intro_c2.png b/genplus-gx/gx/images/Bg_intro_c2.png new file mode 100644 index 0000000000000000000000000000000000000000..ae9e40921f9d2849526f5388aab4d6ac77752617 GIT binary patch literal 17290 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Bg_intro_c3.png b/genplus-gx/gx/images/Bg_intro_c3.png new file mode 100644 index 0000000000000000000000000000000000000000..f382e73b0c71f240427d558049dd1b5a5ee29ad1 GIT binary patch literal 11446 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 umyc|(&VT={ZgK#ku+CmtHtfpwhuqow4nJ zaD4z_MyE9l;|^nf&p`kFiS{E uNPN&rIHZ2^01yPl$M=UbItssdz{cQspVjlZoQyh94}+(xpUXO@geCwr{XO*n literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Browser_dir.png b/genplus-gx/gx/images/Browser_dir.png new file mode 100644 index 0000000000000000000000000000000000000000..e4becfdbd37deb2f438d7991bbed56735ea64eeb GIT binary patch literal 450 zcmeAS@N?(olHy`uVBq!ia0vp^B0wy_!3HG7B;uuk6icy_X9x!n)NrJ90QsB+9+AZi z4BSE>%y{W;-5-$J64!_l=c3falFa-(g^20mQpf@4$A?ubv$FTCGiITF;F=jt@r9Aul`Q8)n zu63_nre+BIS{}XL$g?X4}{qpZT%=2v-HoO&|e4l9GUm;cI*+~ o*BUMX2Sl9=f7JeUXWYjS>tQqRD%*2?U}!RUy85}Sb4q9e02}eKegFUf literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_arrow.png b/genplus-gx/gx/images/Button_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..7ddab41ade56c308ad58a53447fb1e4ad977a63f GIT binary patch literal 3386 zcmV-A4aM?_P)vL_t(|oYk3qa1{4>$3MHbd#Ah8E9k`%$D4$NBy0m+NQ_@PdhY1E#jA!Pxi()p$W*5Evvt5)u-6K`(c@ z+uPmS{vq#r?<8TzwA1Nt=9%5w{q64O_uc3DJ2lzIy2AF-isXOh6+8|uH+{|GARR*p$ zVI@pJ03fTNl#J{=3MWiv-keHnMoC^AI1ch_ir86IrIbk-1GnbPYQV>1fr2YXZ1_%rpzNF&` zGfv;754mz;2Lo-#D8A)h)_$+X$V&IU0X(iKO3MuctEyT9Y&vk{eDUt>|4JaQjH!41 zfIx2P@C~jVCvxdO(R!P(j3NAfKN%Srcsw37ZCJFl^l|vdPeaJRlU}9(5a~Wg%ZI-t z(sh=_53S<9d8K{8QbkeT{aV1Ps>;AmfX6p(el4@*oXW&`>&UODK@dH39sL)=7Z2d~ z`|$hyq@|_d^ZD@ke8{qlBuRKY9wbRZk|ab?B#}s97zwQ0Z*n!T0D!KuZ*t+C=a_o) zT|BvNSs$=oQIwaz4)FT^u=c`>FYS;92E$Cf=P81@W%M?@O8du~ktLBpAV44xz~}QJ zNfNRwJ7$B*vW(a3b+&0~X#hlHaiZfF(q@(t>ucrgzQ1Q&ZXw@ayIji(djC#Ql+9lm zSXI?(;FV{7{=4kKA&u$P&m*N}(XeYBL!BoH27`{0UaxmdV2{V+^s!<6em{Xg09lsN zb)D{b4j1GHi1oK|e*cfi%FN(LKm48!R4IybFqKUl1vU@ZwQ=*V?18~Br3?QFDJ_em zzxg)3%^xF4!&A3unj_3G3=G3S*L4iTNIGW!wvU;nNgxm)lo_Qo`UldoCNN{!ujuY* zX5;2vGVr3Rs%6&&R#i0<_~U^i=Y1DW9-{RApW;o==jgvJBGPjSNs_QEi$o%k^zc-` zR8TjpX`1M|j%k`C5()f%KT`^Wlr;MP-8)+s%rx$5(#`hAE8_yW!8Su^D79={VR6= zVJrP%twvSVC8GkXs_F-R@Y28khbNAr9TS(X8?ENj#U+kk=~pePE8 zqBuU9+9!1&hGC#-8j>VY7z{Jf+eB`86=_)^w!FMg1~z`4v_>ersHJ0|_`;{}GVz;h z0cbq*0v?YCK@glyHngp@`@vOJRXqCWqpVr8hM6;GI@&17K=Hi>pHJtCN6LRV@W( zG@Ut0!OcqnxLp4#q9`W8T9%cxZ$Eg&iWSt>);co?KtVx);}WB}kEUr!u$rc!X&Ry^ z;v1|7pm0_#O${Fd+^(u>fm`7vr<=M0rXC}E%I&nD+J~XX5k=8~Oog?#H8nLXTC@m3 z5R&@jgwsvkexM4zsD~HUsSQGUK_wp9 zPh0(tQ5ChJ1VKO)MILCmQtslW=6@~)xb6zxUBth3mHX!2EahanGuSm?k`xdfTc^9 z;_-M$Boaw)K@bE4L160CskoaU2vk;9vS-g8Cv_W!;XvCy4iM@646-3Tzk>F*ivm#L zRycdG|0emow}sKAmWv2fu+9)9>?XI{1~Rpr!XpVu@k3Dgcm`#z#55)JnP z5X_rSXImXWo*UTT-`Pmn_-O#nMRrzm`||wx^I5udX_6vt`?6*j2Jv{@2~hW7?S1!D z8ptbUptBJm(+%tako?(1dRs9~(^1&%8kS{IU0voz;c?Cn@8yWMB3J{};UN1a3P#k6JunDH>d zoKTVr*dw=X@7}${<8k8gxRb?nT}Rh-=eT{&cA3AL?R3sKD2PB4IFnX zY-ANolcU#~@uuewkH9pY(b@w5IC$_NJv}|t*4C1jmzU%+ZeO;iDp3?2we29)bv;Q< z`<%U>NF;{q3n12anaqM|07Guz_Kd9jlK$4CWKEol?9U<=?oDz98$6LnP+wn9B9UPA z>eWe!!5uuZEGGfm*3;ADr1R94l%&MrdMAAK3>n!403B}NPm4m6O3t1=4nTVTbRzv9 zICX^E7w!EMCr+?&<3?7lTuCStN_r#qG}YA9M+2+qP}2TD6K$ zDCE>0c3?jJ^wUYNS`)6!nWLXy7-Q8^2vV~*Ej-hE9LqkJJ>ZV>ZT8*q}8oF+hJ^OE*Pg_f>?l6I0+HT|7 zuwerLMMXuYBLh9(J#$$b-*Ns!^2)1_eCf2G8L`q%YVLqEO_PR(2CiMZ#_{9FX=`g6 z^%}R|+Or2hJRWDlyvLEVi#hZ951CXto2vPu40krrbN&FO zcdn+W{O+V8JoOc)su+z%Iehpqb#--Px>V}Q+cZsvhK2~-G>i0-2e?xId-TXv)~>8E zfuAahGUN=OXJ4gOo;b|7 zqUlc1q{6x(M$39*scaYq(P$Joy@>LMUO^kYLgRsFn0oV{bKh;#&H<|xMKP}ntSHJ^ z;ISvyEz@%gCUbuOkBLXRSop;I6qVnd^j+e53XfJNyUkvJW`*W(%Og98^|x_m&w9p< zFW|{_%dP^CDT)$F<-6X;z()om@n3J+vOS~g$_1uZKTmo=CFkDX%BOEUgJ}$}`D9s6 zO1MCH% z#?8Cr*2a1!&HGz&%N8PdWRAb~6wT^R3|&JIgfWX9NM2saULO-?euwh=HvrIaawiwx z`)5jK-piBgmURG60NYbt;j03RKsE5QgLO^iySHx@{JEt}zWp)M^UFaHX+5!*mQP+G zeDyQ**gz7TJpgYYo6MUk2+gjga7Hx%gI7*+@x2$&2HIIt``6re+q5gd3Pn-g8x!cu zfL-8az|RIE@dvj2ZlBat|2Dyb3PN*MF|K6(i2jjlmjQub&V;1nhBiR&g~N25*uhYD zBgMDg!`hWKW@ga)8t|9y>Fb7oUEs@s=UO`lC+~jqeX*(G6XLOc{MnPpD4a>=gxLgh zry={tkuc+EgB?VBFB0x-Al!MH=(T2Ke- z2VVg^3VfsCLYH*plLn!^t(C#PPJ6-Vw9JBOWMt)26q>}mIWw%v;@p1VBj82g-LLxZ z(G3B+z=I5bky!@Z41^f|Q&DDk*`)(vpa(b!yapUn6s7CyKJ$iv|1a8q1M5wYd8mN} Q4*&oF07*qoM6N<$f=kwSeEalr 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 A#Q*>R literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_digit_over.png b/genplus-gx/gx/images/Button_digit_over.png new file mode 100644 index 0000000000000000000000000000000000000000..20d5a47d81120f6fe629a5a1958a22bf3957f90f GIT binary patch literal 2277 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_down_over.png b/genplus-gx/gx/images/Button_down_over.png new file mode 100644 index 0000000000000000000000000000000000000000..22860db3c7c0237fc9b84c14bb5d1d0fb8b40a54 GIT binary patch literal 4287 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_icon.png b/genplus-gx/gx/images/Button_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bb89bf530ec7216aacc882c480165cf62855a8f2 GIT binary patch literal 7741 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_icon_sm.png b/genplus-gx/gx/images/Button_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..307580db0860da764445ff48329e3197f957d0dc GIT binary patch literal 4985 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 DIqqIB literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_icon_sm_over.png b/genplus-gx/gx/images/Button_icon_sm_over.png new file mode 100644 index 0000000000000000000000000000000000000000..934bac8603bfb8c2c34b15dd50d3eeb85ca87712 GIT binary patch literal 4914 zcmV-26V2?2P)001-y1^@s64LCD+00004b3#c}2nYxW zd3LqMlrmpR8Iw|)o#iJ)`|D{dNe(AM*aF#2A%uvug_cs05<;}ZVzE611qJH{4H~rM z!3Q6F^>mg+d|U#qTD5A(>eZ{ieDL7GYkl7ztdz=^QlgX;QYw^^_`Z*nlHh-J@Hx#ymn zP*+#?@5yBHQlJ-LC@BG-9)%uNebV&p?J=O-qq2`fMX5(T<^d-sU=Cdc(VjG|3E1+k z;GOpkcD--Vun+b(g6nyBo`>i8N-1?D7K^ac#4`~2@3Pmpd8R{d-BlAr@2+JYJ=qM_au%d5h#iaG`&lpN8zayHHR|+t-(%1 zQ!Chx!1Dz{Xi5qd6Gkeg*JuK-F(9Lo60IeNTLnvBiSa^hocH!A?Rq}0>or=I_03_! zhW+m|&phLQnEXE!0pEP{%>m1oFaKdOnf!ufSw?Z8X6on!V}~WM3_C+S={u}@%jM-- zmn}Oznp=EaPf=FZmx_uCwAPfCmQqkq!0z3_J>8UU>|+qP|^wY8PJ zxTdV9;{2hSE2b(gtXAY(ff_2UXl@bwepQU8R>nBcDDgaBYONO(7Z=~YdGqGf$?`oZ z0c&e(tJkhw`%B;VC&o;}7*yeK)kUqu%@pWB_1@W&X3;X2b#J-!>{ZI-$x|3QbO<#y zHB?qsot|$fhc3bT_3PQTZ7X$k>sY&XErxDk<^;)Cu7aWcHBu_1lpJbS{KvxuyuQ`I z^L?e1s`GvS#zTh=Z9mcdPe{Pp+S&)%QryapO+=mykpEKub#tFTM04i+=kXwrt+O^cu~b*D3~8N_=0Euob_0 z-r|Yp;@FPTQmSp~bo#2cwzlK?g~ugeZEfwOy1Kd-EXyj7$9!f@Xk%z)8|XBNq|FPf z)4ceq&4`gT+;r2;^y}B}j8!~`?g6C~zVGAvK5N#j;of`a(XeYfw|_zMl{pf_P+9s-c+8FPlKokMqlQVP%W+Q)PyT5Epsi=Q)p{sT-I)y5C+R21b)d|y$w z)#T0xO7MI%Q0F+#mlBD@F-mw00UH||dn{VCXq9DIhm@%%EbIV&nC3)}tB=di5 z(|^zyzV@}RQB+iPw(6ckH-MBfqkzHSbU?(0h6b*`{!0{zclge&icy0#t_QEaY4QCh zi)cw0T4|OwH8owCeNQ9%z~aS=f2fqI5dtx3M3QsMlb{@S?{j!$vBP=iU&!5e-<>1h zUm3L4nUsCJs;Y|L{qAY}_-JnVo~EIFZe+@6j~lPD5ds0sE-fv6DEq!02)Jz7vWuIW zn{PHv!x%d>!FlHfK40^ZG(TDBFmTuu=FXja=4zQkw?${f3zJfc!ongR`{iS3t3Nl) zgS{UF*Ij;r%j_v>07D2dx45`?bo4$Q2v}EF_tUs#nWa5EE*RN{&^B!eo5z=?=|6BZ zx7>2;8Leav-5Vz(VNr1po_gvjeDfT>^)NUdh`nTYnI@EMrim!#QOsP&T{vq*+;)=BAr& zrZDI8{nev05{Bdpν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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_save_over.png b/genplus-gx/gx/images/Button_save_over.png new file mode 100644 index 0000000000000000000000000000000000000000..7d1d50012b11ab13a4ec967ab4b05398fbe94a90 GIT binary patch literal 4618 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_sm_yellow.png b/genplus-gx/gx/images/Button_sm_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..68cc1eae2e92b7e3d1a4ff2f48cde53a70aaa969 GIT binary patch literal 2838 zcmV+x3+eQUP)iOA*NbI;pz&el8}(_zg^XBR9{~ofk1%9#ztyu zYdL=WIOootv&WAg-#T;V%pWaYy!eni_FC+&2~?6KR>0_r9xsKqD|;FD@=#I(qbI z=FFLMN9~UTB?r5y-u*T;pMFMD>m_=6HFRCaJHo=3Kb&b(@1yLICESzg!?G-d5QIV@ z)~{dB-o1P6`Sa&5+OlQKF1P|U3e<&JSXj6;H#e7g^X8GBo__mQdkb~B+fUWsx6yGy zCojvOC^t-TzREp!DPXB|UDViLqp|yAmAa-7a~|}v{x@%ul6p6WVGsxec=gp+*}i?d z{m?@X&3xybcMkOfDoGOS)~%Z%Nz#G5ygX^qqD6Ns%!41kMMF~$#RVqQCIm@M41g(v z?ZCuR!FGC6XtcB|{Nb%I2Wmn*|IAOA`|V$%>pF&EuyW-}8X6ju=H})Ua9kSa{-e&$ z&i6AjGo|wK@;eshySrZE{6&=obCQ@RR_2c!IWnWLu#gcW zM%?ryZ**E1YUZ%Nf!_1g5<4a94_EOmcFvU$He8_=lh8&<~5Ug;2sFoY*DyC2{3F7?(PsZVJbl zhG9mX=>k=Cm@*!Y9j`^#b#z@PFE5Y2zCN$VG|l9+w6rgrSnL5{s7MG6!-^+6Js2sA zw3zZp@1K|~4J;K)C>Xkmrs-&!iK>IDfu@6IM0yLkT9p*|uY7iUOva$+ZC)-GypkTPi}A(X}wDs-tKoiVBMAIMM~HM!;r_fD7Fw zLI{KqWMyR`NfI8%*2e8#`z?`a>I6d}u*B6sUB}u^c_a*la5#*t7^s>Rb)>5G@7=IB zO|Wqae9N-1EDPJV9iW<~ec|MWnmYmV$9)Ys6hhZ+65|H~)gpzvlYlf$MNtKE*hW^J zu+|MQ#1)V(WZi)F3y_r&ABEY~)dhejF)>kTZ*NbwZTqU)(uFt_VFDy1rl5p-X!R#j zlouP`I<}=pPC+V$p`vO6RkP6yC(OgD15cO^)YvSq8_?1Y`8gvHLSULEe!m}|&v!Y_ zG|leT)>Z<6K-9jbXL4o+ zl$~By9LQl66b+jF@Rg$CXqInjX(2T=wL8w^@qCb!l*EAp2cjFS3(&oeg=$&W?Pm0) z^lV&xxah;-GDUn>LispdqlOY&}%YE?PLHK&fC^9m~Aj>lK_4O!)sJ zE?juAsj11kbLUR-^Ya0x?i~0uUy>x^;^LycJ1({#jH)@blOM16HCxviOdh8q4Ci^K zFzx7`=+>C3P84uRfxeIfQq@5S__Ps@HcGs(@kNFWOGZ%?wr<^u$Kz>fYHAwq0m#eC z+aQE^Y15`nY~H*%3e&Qzs}hq7R+6OXxN9Y}!K8^L^I80zDt@))Fuz|V7?&duA_7xf z$>8oD8e1Oe!uc(%I-y?E2#X$nl=%1rLZJ|+PMvZS(h`VyVqacf9z1jAOxm;0K1*3y zS--tCQOJ<-@^Hne4Gj&; z>gwuPxNsrvThQ2A)Gec2mkvds*OI#)!!S@31zDC+6a__5IC0_x)z#H_JRT(_CFPrb zzyC1Y;6sP#kCMcyRjXDXJa}+(Fc^$iRh5d03g*t8OIli56sB934poN^lx^GnfU2sB zEXy=BG;sLvVLCcGC@wDEUteE;^Pl2GZ#W-| literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_special.png b/genplus-gx/gx/images/Button_special.png new file mode 100644 index 0000000000000000000000000000000000000000..0ef9c75a90bf102d82badd98ae94eca700c9418e GIT binary patch literal 4759 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_special_over.png b/genplus-gx/gx/images/Button_special_over.png new file mode 100644 index 0000000000000000000000000000000000000000..fe7d7298e4006c35bf93780ce166c101caec34ee GIT binary patch literal 4806 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_text_over.png b/genplus-gx/gx/images/Button_text_over.png new file mode 100644 index 0000000000000000000000000000000000000000..1e6ad5b3821cbba7bbbd7bbfcd3313e89ccff188 GIT binary patch literal 2855 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 IM6N<$g0U>1*Z=?k literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Button_up_over.png b/genplus-gx/gx/images/Button_up_over.png new file mode 100644 index 0000000000000000000000000000000000000000..df777b2f7730c6f3d2038893ca6028c65e8e6f83 GIT binary patch literal 4136 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 OIsn%*y-}v)9Q8kVne#vZ literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/CD_access_off.png b/genplus-gx/gx/images/CD_access_off.png new file mode 100644 index 0000000000000000000000000000000000000000..d7e5f7930837af3302de5227b9a8ff09910d9e89 GIT binary patch literal 877 zcmV-z1CsoSP)4kf_7p{FEkn?^#d7r#*&ItfJJ3DG{a8T*G z-WAutz<}D?+EM`8#>R#!7KCc(!2bSz&d$y_JUqm4oREKYb(QDmXC59NLcW!i6)el5R;z`4dwYB2^LZ@G0)iu( zOeT?1QY;ojc?$~*EG;ehYhQrlIOzIkLp-u(vx#L{9g7FhG!5If{oMBX*L59D(|(!f z74NORSWVMtG#Y_iub!`bJ?#Om>yk>Ph{xk7rKnb`oS&cjMI{mm5{X2BP$|XD%?FcXvA$BZMH6$pp4D(=;&*gL=JACX)$q zLF+qOUtbUSUSD4Wvka|q&E;}9j>GKitluSQb?5r}8r!x5IUxa>rg49Nk5YVJv1w>Qe=GU;^sa}(&c-)X}z{NL%HfyX4w6{#}N00000NkvXXu0mjf D5<-ZF literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/CD_access_on.png b/genplus-gx/gx/images/CD_access_on.png new file mode 100644 index 0000000000000000000000000000000000000000..3dbaa1b0fd7ff894f620dc541c15d43975c8e875 GIT binary patch literal 1812 zcmV+v2kZEWP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ?nn^@KRCwAFN(|mc@?`=~Xanup5x&g1GF{78_GHMAnkIT3hh}8WBh9YJP~&hHhB`iDXqu8Pant zQzNUPla1=357shlBISt}DXWA?+hxR<)`kpC#JZK-WJYeNU62eJfou|TL7j+CKAMKt zKW)RW>-D~Ww)?G~8gCf}_sx7965t1_BBo+0!S> z^|#MQf3H4Wm%q9eK_gHmO286xC^3H&1V-Q_AqNGCfTTlo8KeSBv67)oR$1ssHZmS# zMOH8gGLfJMFfr0_6DrP54fmvlF#*+}$QaTo6l95IQY2RM+rO-R=CJ`LLj;oMCV-;E zC|74mA*mQf(3vO_MzEsNTr8||OrYemGUL-O$Sa&&owH4nI5qQj?!3qau$sgTvOqxe$Aqt zaeusIa5%^5NUmwcb#*Ls;Nf_n%Nc%0R=B-f13>|*tgjIWL?{W8B6xo~@X>fcfa}0z zBq|+|GrNsM8C1@GBtg*dFC^46@k|n0MQKg|q5w~r@qE|wlvN%!pj5g@ju3ZhPYH1v zjZ-yhiW12SI_CSUW8NGu`KzB1BQXS$wmE{^$h9QZdALEr((#*?-3^~C~a*ig_;FD}=A|ElSQyebUAZL27gGjFVF z<=8409`p$(wdXu0dV}lMv709DbSr4is`e~Z*-isXiFK{W;pzSc=RVL?WA6i$eP$$Q1thl;#95F9FIqT;#kaB_VOhKxQ1S zth^`b2ud6nGuR_SL79A3y@W}PeI)x3lg-BHK$93EapoGJKo&9@rrBqj<+(j<)9-gS zGg>xN+oBMB-T)|tLKMoJWzZZkC?J?4&TNG3N_AQ$ErWxC3v>1s>?}ECGDz%l4sIjP zA)QGOz-03qA;Yf<|9^)z6_D{6$$zHlwYr`BHyRP$3J_+D2Q|>ql>I46eiS^yZiytpi)p^XjH~LqcI8;==>O^ zo=M7OQW%p>q?8z=k*(R7QE*?8$$f8a;>S}w`Oe&#vuDrw-gE9f_uLD>)YOy=g+fvY z(Ga7(yN+nnER#(gB_4Sp%@fDuW%uy^B zSzcadaBvV!2qBM;kBLMgK9ZlB06;#UXK`^60T78qXf*Wn^Z-;6XhgKMv;fdl&*1+4 zo|TmqpT4cFjrH|)PEJlZJw5f6%l!O2mSvI6W_`Y+qoZWAS&GG??_XbEAEs%twzftz z8f9i?2B_5g?(QyzVPF`B&#&$dl*?r_O;e)^*L5ir3Q8x0@C;4Ua2%&5r|Y^NuDA1r z!(m27M!3DbC6!9yx-LgYM?|AhOw+9CS9b@hhj?LOfmkdC!1eVto12@S1D;4EXl-p( ze!8wxDwT-EV$9CYDz3S?IVJ15u2xt|$@ccP;xkQ?uC6Y2c6LZ6lNg3kH~4oGczk@s zwr$SN⁡CfI^{wZQGQ~WgN%Bwryz$70Q>vbMtE($EHa0xn=hF#PF)%Q|^z^hx*WKMsCX)eRa&pph4oanxk`E3J>hdO&NoDIe z4&iY4qflz%!vp{>E-nCAU0ubpEFK;n2nK@y?CtG&Z2SBBm3)4F4phoyXlTfnKy{~} zvg-c=O$Z?`FE7&WNx00hRz z$A29j9@5d#L1$+tfk5Ef0mIZp3}bpMS=t~v8V_D P00000NkvXXu0mjfy(D^* literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/CD_ready_on.png b/genplus-gx/gx/images/CD_ready_on.png new file mode 100644 index 0000000000000000000000000000000000000000..c4865963e1cb74a5d7726dbaf22b9cd10ab21106 GIT binary patch literal 1858 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 CJutM3Q?;QQWw5csKo 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�^6o*PRF9eWrCK0_KK(5E-AeymL8)4 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 Ef_F4S?EnA( literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Cart_ms.png b/genplus-gx/gx/images/Cart_ms.png new file mode 100644 index 0000000000000000000000000000000000000000..4de57a935c5e44fea860faff80253b66157d3171 GIT binary patch literal 23290 zcmV)MK)An&P)EM%syvLj_c=0B zYr$f#z2=&0&CjS&V^n>sYDz@#;p4CV#;+cKaw+@P8}|<@U(b7X7&RLrAi3}ZjCMA@ zsW(s?tu)BSF*5QeYDH}w|VR{A_%+Y#f9B@TJvc|fs7*Wjei$&84^Ri4>}qUIlYKCdS> zlvmRYPkRDuoW;2pr8%nGhPs z9K4sA^W(-(PY2SMcsyr*5FI@S-%Ph`+X-Kskj`T`Z(X_03(p*8??i(0EWBA)%o5M$ zEA}p=){)dX=f)4#N1A3nDL349{m64Couh9oIrF?6*t~HD2v!_Erg3>h6kvb@ztf zfAfx>OMCajA6x++95F7R4v+zU_8VW{e(?Ecd~Ke}PtOJIknhgS%QcHQxi}(9nkS~y zBeEL%@Bm3e=|Oear)ilSvApB|tFhiN6O(H2LGqpk7g{>-$$;kryrZKH>?I}~C&^LT3P z_D^`K3u=SsER~1TJt4}~p>i7&(v4Yz@RjX&hp4jbui0y%n-i_Eh;cqWGG9O8koRPB zY6Ovu$MX^2Hq!MIu2e`yi2DDTllxnUg>8oF1^&N!L#(6^bS-I$H`j-ZRe!4)Yarby6{EH%hjHJn(+pU z&A3DIds1?C%YlQy);oJ9k|||-WZ7k&>}F`eMy8=`t)q|k-1N?2DYRaRfG!!|jJ`GW z$pJJVGTwvZyZ5|%{W+bKXXb~E?URdRcEB$GdIn&gr>D=KvwJ-9H5%_V;RT)+SVY*w zkmv})Y?Ulh40@?oeZ!b+#pIjD1$47CPo%#-lg6uNPhjDs~) zf~6>k(t08V+)RnNcNTZ9N?-)12o4(T>68e%I3jRXr)1@3NnCd)dE;7@G!34Nu+hd^ ziLh8jM7b&s613!`6kyKcl`HAol!;}li(CO+^OmX(`1ap)babCZ;Lf+q#^BadMOi)~Djxz3L9 zfyePa>~oEAGZnH2)hi9@FZg{%KJ^&7@UWIBn+OMXjNEp;&y_iHbRUg zfw{8s+-$Qjicl8&h{?K$l78n5J#p zo?o1@0V}WpbvURbPFv+_J>wV_g7qN0f*4K(g6x7sBZ-i3h>BaMwT|~rQpm~4Vx;H@ z6^THilO@O)Si^fmF^U8w2gw5Ujy1!3Kq+MD%*mNbVJ@Jxk;2GXIbuv%m?xp&&^k$l zr6iW_I7Y(gz0zaF9NGsSI>CkkYJ$*E$)qscE8dNu;bwmh4+usQA3R(&=rZvtlM#2QEC$Mu>oO z;Sm(0d&RmFF?g~CAzvK4BnPX6DoKRL{FWmb!Imfltr9~AROip76A`ui2x7W+PHC2Vi%CRp|z2%F^7`^rVhCo#hqE5 zuue!LTq!-+nX(gQ0TPZN)BtTx3S*kaLWw()6V(H)foz?ef@lpF&@#d5qz((hEPx94 z7BqJjlp;U`xKI#gf*j5QSojFjQV^QhIppT3G>TUUr$;dLp!N?ufm=tU;jT;;>|NPO zVqruXpllIn9Zo%G2kVFjg0NnAw04q=u-6SzF0eY;22W9N5$-zR&Q25|hzP`mgfIiU zaF$@Kmo<_GrXTF%Xnf#_kM^kMf6KN!r24ej3maK9Lx|8G~nnU zTOhTQalADgK{dnXlo*j&#=(79J%rQ)?VZ^j?~aI*Ql{YK7A(QoBOw5EhtdNR@F_42 ztTiMFy+AK;*3M27Wfm~U)Tq(vGx)4{9^Y^7I7&CL41F5cSr4O$(nYaQWLL;@Cd^SX zpm;T+3(SfoXzs`ao)T6C7aEA!`?fSXD){} zwsqcjGG^};i`aJ=w{bsi1WgFEk-cd87Ylft6}$ts5qI|EO{P>&3rEAJF^oQeikJMX)5 z3b?io7Kk}v%DdipSDj6QeXocIiQ#DXJ-9bm%$N&!2#&D1@nFH$g6nN#Y0g$)yYM`U zlU#TtP#*{1qXjMCE;`ja&4c2>QQ(1K>XjYAVnR=Xsc;nG81UdDjfs!;X}mM1iF0io zw;;LWro3y7w=HPd*|ouwzs%#XH)l!=!6by$jr$H}&eggy*WsWp!O7w6239(|+Qtj; zz)iTL^ERNgjtS$YkDzVA+uEoeOa|dbYlcv%D!ezCTPKSmkx3S8-nk3s$cOz3)}3Y> z7Q$V0wg}$H%2}M+oP7jM3u{i`&ZiGY#GI;yjH$VX?f zfYdmP4ch>;#xCu^_}b;>oG;F~0b7P~#ZIZPo*wy3jQ5lCrh>;EJA$4+=t_@#*T7xa zZ}(_5&e_li&cJsK4s5ijlo}Y&*m&n~5?I@jciWk$hNSWM4|;GkVSBviwhPIeR)vQ- z_}qd+G}_vTQ!r88)*4ZXUEjR+-Gq`OVt8Gjz#)-KwcU?k_y~1CN1u zf2ZXm6~wF$Y)F}BfHEA^98gHg^+m)et@6pVXRpqdI~oCLqV|gS;8l5o zYGut0Db6{Z+8c*y&#Ngjr;Sdd?k7q!)-Yb|Zn!2xS|J&IF?`!Nd*PGaf!hk%f-MWj z5)`{*P7|;8JFv=>l&-=djNDH=nXY)27DyW{g1#i?e&%S6Pj=T#sk22TmBd^tpUej) z>1^3Z0g(!|ZHNmm%Trud>eP|s9K&hWxSbDtB_~QM?SSr-CGDYHLc}kO&Hg`mw$8cJ2Jlh?3nUqpDx)^Ogk=9WXd%4_< za!FkwJ8d=^8?H02rX9CU&~EfOanR1>4_v2(m-B?gg(nMht?Z-nbiUz<6kID^f;uZD zovG6K>i&i)ISO=vV-Zq+U^f?D?GA`GvLG9wN~+p)I3j;-Jb`T$p?3Rhrm&r=b^dWMb`(Rp*stw8MrVVw}R*TIWhL zuViAjAvU!(lj_ECHJ+;Qgaj=i7IcBODkp>&DRWzuY)%j1fxs=X)5NPf5iOX>bT^J6 zXcwMT;aN)13N4H#nbgPTebEXBQ<^H12}|$1vWW?(Bs2sloV%e0uOt(FqN*Yo$1rN^ z+@``SGLspG()x_nm34KVsc?frRm6h^)J@n#cp;hFHe`PjWp>3~xw6EoHbaw9sSRgm zkh}1-3C}DMt&+{_z z(v_(@U6j@)*hXmhRFtboNKJ@C6IeH}B)lYZ(-iHBX{IQIE4P+;Q75Fy$8di(XX=&b zRd^y9Z%&tB6G2wR8oX$QxfzPk1@-_n*opEyWl|5aD9stUcZa8&awAHr4gnTmO{ga9 zJ+Xw2Z>m5Kb_TQQ$e%692zX`*V=-7vM%~htB?Kq2^I`uT%A!LtUSbGviwQed785)i zL$Cl$A%w*RMbQ9J8Ha2astd^lRT-~s$TxH!g4`vhoq>A!w_Nlg%>YfDZjPF9BxtI% zFnUxvL5qfjBB4~TbPG0blN_Q5vuaEIOS8 zINhM<5$0`SY`!5;!5vd)^YOgMf=eK2=suAGx4^_PjE>=IRF{uDg3+R*p+pGPH>4{y zHJ}aFFY&afbR3OQDrzot?=+l_W8#PgqK=DUKE#TC;n8r+#_RsTQ*A?{5uPxd%`fU+ z8a(6+kB&U1OJH=mTzD)#^2A4;ghfz&gPy6mVN_c9N1pbPC!zF`N(7Z z89bNob&L+I7yD>*+!H2aZ#WG5FlsZw;0gJ_W0)9$U@{7SPU=QZHq`7;JTl1*?Lle};A>I09Z!BbO5duNUHPx0`PC$J3OgC2pUMhnBsSZmjymkUp3 z9GEyZby_u=23;Cm;@{vIxplkPM>MdcROvKgI8ia84IaWJ4 zkxIy~y(Dt##A7>JT2jYMC9Bue18_Tft57nka!ON~4tU4FMAF)9Yx3(b`+lpG)d zZjQTu*)hNTIfS>5%|!xhPUwDNdVHW1p@>5U!O>qhDggTOf6gpV*D7R$B zy5<~^Z18A|=WGGdMiO=55dp%!;E|yks|HDx5dk`?6|x~>h=Rx{-$-^c9kq@)^fXE} zk{p>kVL@m|3V1U7a=^tjyurE>Q=;SJU@k)lLx%hpk+AM~c6v5U#~OJw%z|)7rvQy{ zVCRafAU+x&Vy+|P#UKR{PM8y+WIB6OT4Yu!Bish)j;iwKeGCV+2CdPpvm%_<;QQ5C zd}A-;R0ko_#%FbOXx#cE$(@>wRD~7ivlcv~bMR5O?BQ64&o{X1;O8Ms;6{jJC3v&J zna;cowNE{0DR}7c#^7-jL|MUe&NB4n|LIw(Je?DoC!W_0b6HjhPu&Wgx^0};h{mCH!2<6K#i7zw;NRH z%v<115er%m?$Y2nZI$pqR%a5&vUBh7+QGJsUK^=1dW%c&x(3aH={(93Rf8WS=hWcp zw2?pZjA-JsZ4~9N;W2oBQE|6z!@8sApr~Qld1vs>AhwlOE80do#VH4`+ekyE^Gewq0a}99h0hx- zY6L5~1zCia;9lT$K&*`#N@_L^AI7?Qhk7!0(m8LAhT(bakt;L$7R1R}3aA&}TIY2e z7vGBv7Qx$oq9Z(LP%FH(&RK$LuxMwM;PW25z6)w`b_%j~YB+ZlR)eLTST!-)CVj%HD*{z=|L)oC(e-D~S^0w6&x>n)4_^B{)Pv zMcHs%GmjEH>bOy}jSwdUnkZ*=R^U;EhG3%HqrAm=PhxLM4I>=7D|ZB;!kfsbj8K;9 zv;y~ZUhZyL`^LGS=psx_SR;6!;R?5ePK z!`5|_stjHqjl;fR1>U}|*qlizA!0O)QvinpB;|B}!m441JSqbYk2r5?XOqm;%@s%A zSWjp6C^{E5D(`?TU@j8{r?}8@9>m#FuR;rbBOX?PTr!7c z&o`{|;?hr9Q$sAUoY?F{bLA`fiXG6j;T)-&I8VZjWS*wN)#R*dEGeU{5)pi5zT%Ts z*m|Weh9o1eD<{vqoUXZvAX>*}rAR}4C1>U3Za>=Ua3Ux6Vnlu9N!jtFWRe&zL7y@c zXV$2^+TDL4F4?csMF{N z-K9*_4Hfvxbj7QhSiNEM2-{UQHU`gi_@Cm*zA~4@i{0)c4<)liL)ww2)1D_ep?YZs zpOq44nsi?6ZxG$+Q&2r~XlK4w4$K!G3~E+38xtX)*vlF2)lH9ciPb}D- zHuhRDgIR<9r1YLRdgDsqstdD0Z=}D(&33I$qJ`!vHE`90$-y!~He635y&NF!Z%=J-NoZw{}kQ!t+3=m#OloO5eDvEatw+M&8*DcF-a z^+v-7PZ#Ehp(ZCd*AaqV1BWKar31-j^wjQ6xxU=`GP)YE7W4+U9d1HUQ`|>nVJ(Ol z_L*$R?<-DL*lKVHxXnUpkaRR_guvF}wkt~$rWWJpBRF+ouEwIl-Q#N-5X>}Ij==7? z@r_q6c=P_APuI#d6K|;80s9S}<^%h*aC$iNu&%rZZWx6~fILquS67_t#zWi4cNg%r1QP@SZG%n;GV=OzzB^GlyRG5)=*6xzV~HQph=@7ll5|E+xMoE`JZI9u zqZc03nJg$K%nro`H6e7YLmufZr9)ay1xyznE*nb_ib0r@wUaM{P{Te#aiN$qbeE^~=A=&%gQvM7d7Nl>~3U z{{ue%!Kb`iH$FX{_$z{MZmzN1W>cF-i=ZH!LSC41-}6G0;(?Gaa=o z$B{gKN2OE6X(?d>U4y1RqHN?C<3HxRfAlT>>;Lk<;@|z-e}~tv-?4e& z#miS5KmB9A`w!pnGrutNpZtUWf}3Zr2n$NvxFY!Wzx-YP+yCajJ z|K~h=dd(mGKflWV@DKkH#S8z@fA;tJy+8QZ{D1$;|AdvXPb@3uU?RAItDsXMhte-m zgM|;jGD9@~cn6JeWJpTntW5L7_5O<4W0XK7E;Xhhh07)C$|0Qq03ZNKL_t(6i_6!7 zAUShRhL&KR5)p}}Ljpe%95pyj!C8ZIb9!-7X&k$Aw8U{%GNU%-i?C)m+UO=ZE#t&g z2PWkx&S`^r8aGpti<8Z;YH+O1z6^0Cqs+Nb@_2U!wNWZik-?)QY$oL6ItU;sb55P( z6s#rTWV$pYIcG*c@NpV5oM&@vGE(jwXXhM=<1D0L)F2mS)uEL31m^|RM(KbVjxL-U z9B0V>1y7sdEWx=4yJGAJ1ZB>dl9l|Yc*Y@_{b-}(ptDa+Lp);-YZ^Kk=J?iQoKt{{jEvpZpHT>lt}*P1`H) zqGDO;W-Kxe{YM$Y6IWtrcdTc6H@X=CO!I?r~$jYGI?NW)TYi2e$<^C+qmkZA90gl!uZ^rA4QPcBgw{8L+|6Xecgk5cceeE zI-_+nR9|#lHFszL*@<%;5Mn~Es zXJg!;F5F4*x*1b)d~QKHpP6N&OVBPnpLOFc!O|YECaiqH^TRsIM$#U+>f=!H z*m#fgx;eXOcz1F$1i_nfXU2OAVmpnzYa2IW_rbIEpqw9>+hyQf;bg(v4%^lVJ6_5x zBZ|0B!`}Vj%q>B>3`c}Ip8@~zU;B5sxqZUfgu~S}Km7DZeEZw~8fhEf`J+GK-}`HS zmG^JoagfCB>W0r>zvnyO`7WRR^MA=C6HjiQu%0Rf8v*a z_1E~?SALTFclXqk`P@67{Ms*b|9|`r|L7n8_tf6_;n66m)7@BVu=DX6-^Q4XD(_G1 zw=rz-xH+{}MpNOB|4;z;k$(b1MsJNQnUf?|&8#VLPRdymYaU@_n`UaxtVvl*W|Ke| zH8&+jyOZ}(Qwt|akW^4j6qWIFDNq?r1FA!;Qi;pgak;H8H@J?1_9%4w7wr}?awU=R zuZ}rhk|tzSxyd1PO`IgL>3Gd&70#-x3AUuPX`$xKmXx&=&V0cm!IyYCxRV9aWuUlR z{-&m}pot5E4jxeu{lGJrvI*MqK3PX;L>S#R`oS(=vh7EnB!7zM!@fuY zMU|{N{$>mZPBJ0`F&}m%#yqAbCSacmr3Ui2BKI3{cjTA8_EUWNtv}@3|Lk{}S0|qu zyg!jo8@D>s@6Y^S|MYkG!*Bn;?DE31o9DcJ^Oo=Y(Vu_|&tH6nPrmv!4$FaW{`AlA z>e+MF$I8$A!mm)SuQ@z>%F`Dw`M-bn+x+pLd>0Wo942=2%x;?5%?ryivrL(3QuezY z`~A!^&rDNcDTO(g@m50m=j*ungM+r#urPFXv_@pPJbp$UshlSWp>xA8VFFXn|8HM7}@%^k@`MCVNA60;i0nJFo+b_=DBnxds(5hJUaCv0K) z5>L~D`y(YXU)Ni@oIo8F<1sp>&hvTU#ih*BrI9t$*T$6K#j@l1rmVi=vq82oBdeKL z^Ny=6Pz!9Am>Bk1a^}@MQ`+dXu^dd%nU0O;W#&oI(Uqi1ofO>Z*x+Gwe|3Rn5@OqU zIv1XnJ!%`OO3T8ePO`?$e&XPTQWTvMJ}Yk@8~^lw{U`j&um2{?{+hR+eV_htwpkmtlV zB}mr?zWR-Si=X?oUtyaP_op+jZmxNA`kdR{HNWz6zr;WP-~LaY<%QB8xdxt;!qSb! zGgZgMrvg{IiK|IC*NHyuNxcysc<*C8?Z-K&Y8u^sF$(@kplxRkn{pk)DTHBw>mF2d z4r1iySb`}963)_voxqa(GIAr#N!WK~^3H@YnG)SdZb*0L3eAH#8FK}?6RJ!pSbC5I zrfQTHmlG5`IlC@QZIp7fjd(t%7)oG+rHyw!NHKDOn-14?yuVD-2=by&;rje zNdOm~I?5|{xqarO>^mG=X9{C#jExzFrorO`vpRDfV+)p)Nt~rSCG;atn2-9P#Q)#k z`~1q1WcPia6A_tJb>Dma`uA{}Lk$JXBxfXwq#?kvEx_=?-dd93g&}CizrahwOK-h0 zVA!%DZ7c&a?2T=KvH`=OAQP4#*oG;RCS?qVG}+TV{p0<(zp64L;&^c)va<4K)&23h z-*ornw{g2(WmRTIWW|Yd;+*d}!KQ~cDJxZ^Q`8yfvnf?-R;52qO#|2dtVjLnbLMfc zgq(OJiL_Hl(3Gke>nLn?nYFW$HF5O&T&Ki}#H!1d;jalwf5hd|pKKJnoud`|eby+g zOEjH5(3HhWe3aj(MUkDN!8GkE8Xd9rM=J zID%%n5;ls#vN3Y$kIT`*My~Wn70DT=4kVKuge(NL@QF_r?#ZQn)c#QVW3wJIJ|?#I zbZQ>nWRaHrU+JG+)0{>r7bi?Ia}&{_KW@~YT~M|;5d^M%hx&;6OmZE4GGD$uGryXz8JRq&RfDkK%=+cj*4y>>k!-(@&&III$)2M(?!5KKoakmg z*Y~NsmhWm7yk;aRE@f7-B9KU3#9?8Yzx1o$xO*ZNtCvum2TZe)eP5Pu9HLUgFQzeD9b39M|VB_~iL> z(x&0N-~R=|n~&&Q$J;;q0Uy11X4c&Gj`!dD8GiZuzrt_))<5L^#+-LPmL&o9Jd9sp zN+7B^WEEQ;iIfzye4OiN*(^Ds*|c5&yjpfc4vCa9*;z_Y3cV4=og+7iq#ZFt#Fy+9 zQIZ!+Gg7glO6DiFRyPh2k8{4Hqk^UmO}5a|64a*g7Dn*kouF-r?TAM`WM^dYj{0=seTUf|u?3}Hk?;_?LhASNY%m z!EfMRZh7{#{ z|L1?6zw&SWoBYFn`de&sBzlWBu?ZMCr0}B@iTX;Vi9Z=PdW{66Go@msr8$j%Z|n zoVZrFKsnbAa|vXU3KyEV$e9M%E=!3JTN7tO7IvDs z)dDCaaMDXWuebKN{42PAMUc$@DJaRk#}Uhf#mJtfXu+ zcdwQYs@W2Rf;8HVJz=q6)q|zTprxtcdqy9J*dXy^>t^~Yh)ks1z{rmqTzxf;g6HT+?+wZ>1ul?nJmFCHY4==BI>V&6{ z-r&FczkZLu|ARl}-}&`l=iT?;=kovii0_0o?}ZKDdi*AzUw_J{fAk?QcOC!7@BA*C zZ@te4f9cm~dW)AodG9HkHt^Y1tsRJPr9wqyMQ3dPKAqX749~{)oPBT zKJQ1ICh*MrGT&vI~3)1IoT0lfO zFGaiBE+SD$QNh7^Qa%!BRiLEtk%a4LCdiMwEkwojrsS?wIM0ft$jTdmBbELm_8k#Hv(;6!9*X{s_LyJnxljRX#~uF4XS5 z?+YF&w&5>KmFVM^Z)a=dGCX7@%i;NzwcY#-t|2H_)qv}zx#som(TfyU->2al&r?H zC@UP#pFQKn)fGDxe)yx0`PuLO9J}B7ZPLXhzZEl|fAk|#?9mKY=R0=Z;i6ha1r?sh z#4anl^F)^%7j&GXba4l2dAus_7A8?y?}Y?sO`!3aRdi@*N#bd934wUe=JK2@nH)T* zqZNTJ;srMJw2hG0ZK0K^RURjjx{k&Pc@+q`(93XaTt}3|>TF}Vc)K3oHl|^E3$LvF z%5oBc)_Y_ZNvUIvCj?(Ke8zcmz+_+@TB2Bu+z?zTAZA$vO)f5f=Q!(LLVy%JqMjfQ zx=0Y=j2&&`NUIhft^B3)jtxC@JwAw4bI(RgY@O#U?!aYMn>AgZ$X&#@t<{I^ExfY! zE3&ig8XE6m*O7D2nt*GZv6--Ew^AdNuR=?wR<+?+e}WUvx|c|BB<~@38gXc}dO>H} z(KL>{YOUIP1n(Ui?UC5yrv34rvwn;B%4)M_7b3aOgto!Qg!Ub+^Q@ZIG(zc5+U{&( zBjAD~t0IzdPFNR>-!?6sMzUl=>+#<4NF$rj&@?M{M8sKmWtB5$a>d4PShayIW^J{N z=V#NFPk;Xh{Da^B0YX`$Q;NC)-`TXR8{y@rFZoCR!~a6Sq7c`>yTH3=!q2ZffAYJ( z#~=Of@3Ae)>@AE0ld*8wHd}Se?GOKykNMv%O|IPU?Tx1qc;r_!n-zVwWtY#1v+Itt zn0T`}<5BDA9E454=gvY;DG@_qrW_N{5PRCbC!joS0`F}aLVv;8x@9e`&GuxxbC#or z<7vCWH?YRzU1z1Ob0mbo)6g38$0ypR^jccmPea4^vS{@F5pvQlM_$d7HN#P zxNcVv6X&}g2fVRvA(^lS=h^C(Rlj2+7E8k0I@*cnN)kIV?>1{vNN8(ycHJ)Xc)d0u z81=_r8NuP{YJ+PsYYBMQvBTEKs}Oh+R`?QsZQGU?S-GI+QQLC1SwZp2u6#gZ&!uFZ zwkrs>ZeO)4wC_3Jb_5aLShr|0Z(i`8tDIT)9cR+83W4mkSOktuSrWY0ZiwDYY0cnw znK#xOTKv!-D_CtK>gjregv`bTL>xO2GL9P#?%4vtG62UC+yHN9%+qE9;MU4(~jVW8!5Wtv^je_JwS!!diMF%Dc^) z=&V0ZZ0+m0WaAue6)%Kc~=N(=hZ=JQQy`@{yI<~5O zesRg;#`Cso5e4;*C|HeT$vkcvTG!CKjCx0(5-XR;C{H(LrLKeL$>TMvK9bHaX?(!B zz%}uN22DL)Y`vFaVwcu*+m5ravdRZh(PTAAQ%RO}yHtYK=8^PS(U_5lY0g^OH1(vd zIVr3*3&d?AbqV!WA~DB=UUoPa@X1U@joC6eG$XxQ4VP@{KJB7q#P>GKI_HoCNWy19 zlM=VPAzP&Hds5e16*UD?Msu?MMB8G)?Fs?Hx#B@gXtJPh6BU{1kB{JcCGH}z%d`RO zkJkQJF)!IAa&P_VOE@Rs3QHuBx1~Rw^(Tmsts0f}CuY*sws0$+Mc7LF|Hm#3y_(s4vn&8NNvi>JKmPq8}@FFx$knFHtfe>(- z?DzK$w{Fp#t=>}BLKOw=B7L%uTn%NoK0<_TpXvJ@SL@d5MHc~FgWwE5xAaY8W~>KCgKHcy?@)p6Y-L5JofVSmb4J%Kx@t+Qm3iZ`g7@GZ>NEM# znz&liBZ!Z5z9IFH`^>g&Xq<6)v-7BP^ld5laJDfXOwPm{xo!eEH}tE9(6+eXNzup< z2_@#9e$`r`Wf86ruDTs(Z9vradvOS^6;j%Pcl4VTIrXUXc%V~3Qv<7(xLV;F3jq+k zJ^Y=L9mL}*$oe3fC>2E6m7_?II)q2C3ZbELB~<3i<3%8~0fkX@!>~o=g_JvJJl$qh2D!Ibqh|Wf5myaqy|KK9n5?j) zfJCwWgoa)P?=xM~l+tL9T^nqJCQNf=gt!W(l^&g$7rA6Yb={8WN{Q0YBBTD~&5Gn; z*ESY)55tu4`#FE!Sr& zQy>DM^nGTBvVMGqHh~y3s+pLTF7;%Tc(y?$(0k<~Ca!u*LeUh-dP~WZD=%!@K4O%EV+<5OVv7trNCoJt$si8qc*`6*6?7 z@m5^SxxmJIwmxv#t~qZ!Ud;V(lrT^Kc#Xr+1>3(QX=3LRx@ib!tp$RE;C!jJh|srz z{_%!w8z5U1wJRsQ$StYyv<~(K;zh+t%y5eRcLZi0-xlD%hq!l z1kp@bIhwZNk~LSoaJlkU+o-ke3D!=y(1vU0X-56=PRNa8w`pmchFvKpCl17WE;cRO z2`Sz%QimLMNFZ`ljJ$r`hw&>LbZ>~0+IpM7F_-rOFlQ>2fAG zLA)PW5w6UrQV6IqTPzC^+n7krK~brL#_6=$LIMQm?HX7tQ zaLxvTl)yU{1dd|gaUvz4Zk*7RB5m7{l9h36yoan@bUQ?ZwrT8+YFQx`G_m?RG21b- zZIqyPzdl>`2W34dszb)lutroXCmGeYB4|V4k#C5dxnnKWpcWFd^s(UlK-lQKa@9r7 z+Qx_>V7yjmi3kWZ!LlYA$_7RvT;xOu-kwWJ#&Pw|+MG>D6r)tO*j_K4W;(I;uoMrk zD{4=3wu~Al#AxF~yr)kV7jH`V&WVMzplC}~Lh!^~vWnDlLU$<=oTqV~T}p$`!8^Fx z^@QLlqFK1t&}R$P1hM0N%7qMId&YuI_$qdiMOCdh-5EBnwm_6p!!IR5adtUM%+gs* zbDN?qhtwEu;*3X3h8Pp8&|0a~T)E;xOqmAdkyy>=E0oV;gIpLfO&*#W$G=(J1koAt50}w-+uBIA*^WorfdPXL479p zS_?K8{-D)c)!|n&Dje9$(8)5j&E8MlUYhHZk@0J}kSjf?Pq4JXI8w5o4aTq2-=I#h z_10ybhK^3Fm#p8x5(jRI>It}Vp?be*JCwr*H11zbVwlc)l+R?eHc_C^9kX-R=xEn* zYK$WlBMTJ5?$B|UZ5^!MGy>76c%Zgzp~KQwik3k^5;P?pD*J<$4NbLMm_tU)%rGm# znbwNgoMQ)%Q_bVdxQal%Kjpc&Qq(z>2crVssBxOh^>Q66TI#R+(KFOxY$A@j5fjLM zOyyj66|?UI1@tK*Pf>GT)HGg--&t%XKUveI4vT@8x;CO^92KF=gacOmN!Vs8TExl zA#Oh)WjsrpDJaf?vv{^Rb8Mv)OAOUw)~=)vmfM;st5$i>m~*Li^&YLy_G4M?x6#rU)G8?`*_L@Z;Ut2yJ!HKH zTrfWkp0&9;AM~kr;vLyJwyDFn!G1hSy&@Yj_HeQ}8WbtK z!qQf?M(sy@{WZ0$YUTye74k5!1wB6)3X!}pOS6!QJ+K2302HWYno=bSIW7h zYni|YaV5vMv>};ixa(8d0L&h+j-IhEJ`nSbSV#f08cgL51x@jNqD=tmjW7Gyy#cDU z;%P&$O7m(HY4(m-t)-N3G2#iRU^^S+OwL6X6yrJrRzgTov8_9T11(9*;v7C@KK=2Z z{$2JqWz~ENMrFSS`A$&|&R&xrwX)mhAkL&D<^GS9^iL;^%^Y@M!Gc$UbK%#a%&nBM+N^AH$(D5Q z!L*?>0gmMamoh1CariQ~TX+wug(=9$dK+xDx&$dlC&PI>)=LdjG<<&kjHX$=)#od@ zy1u&u;TVn?s(RZu_9-__`FbjUB_ncpf1LWiV8I=c^WF(GI5`KWpbjZxU>QQ=L6^!& zszog85>yy0L{%M3aR4U`B0|=>uC^ow=ioc}5YhnfgD9T-Jj+o(v`yooMlC2*X@+@CECYF-Bsn4eT)5 zW!x2J2lUn*rPQ;jubs<(mM#KWOeJZJC#W7GFD^>AVXF)2#&ThBk+2@~SOlw|a zv7vJ;%WTWwyIio~;dtYXrxZ1aU@`3G(HgMrESwr0Q$^@gPoFd59gPpPJ`_h#^#tz? zTP<`<%_SE(7e-jjgO#YR)LC*KO+7BGUT|pQ4u7F(R&3hUul>n~AO7Q~XOI7KN(l*` z-PP7u6t=pz3lCwHk|>QL*aAEiX8?kcpG5|Tk=9_n$i9Mod0(AFF-9vLk_Y#270?%0 z@b)EpAzd`+f>%PfHPV4`o{coKi&tib7Kc;t=Em*&o|H4*2VxVrR=B#lvSRNy%9WHV z2~_8qmhqj2?~adW+w1hdXFsNIIElFKcK^oX_2yfjzW9t*8e)xqJ{Y&JL~l8#3g{LK z96tv>$AokXw^l1$u;3)FuP)h#dMvc1nr<8ehUy0ZBEBe@oAOb;*{O_9(?v5Os=B%> zOT|C){&)W74?q6nzf~_Y{$ zOXrL~n@fz$IXBEWRlAlmpsaQ4`KoEGMXQj$zy$T0FP3hy;HMJR1tg`O6l+%j5_<#vmXzKM}Gi>C+o9~#`NbOKYIMno;-dc zP1EqsZU;_?eQ&E)%?Awu27#->nR6z_NYmKnFd}00a*B}F^Qy4c_w_YKtFO~_J3jmD z(<-15a}@0`!MwuE+(m;fcqP35{`&_@uDNB{RPg|V;<38Eav&2S1dHQNj;mT(+wFEc z$W0Z{lroQ3XCHs~*^kD}JJ6uls`__TwZFW&Y_0lOX1CiF8@a|m%b6lW&6%!kK6HhuBb{UrNrgs z<&A6B@$S9H7ovs~=2OmlSs45&xMqvqwcdMrt_VpxovBsoKA-0Sgw~if7NB0UT(|in(KB3~V`jcjNQEpAJ!5 z##QY*+y_9EU;gud@o)b2@BH8Y1(WqBg=GwIzU%vMH-utK2Z9Ep%*o+wGWNob-|t_K zcWS7;dj$L0Yf+F3zFh1rwef(JnPbOrQ(sKY+Wl*xLQXusQc~^y;1B+w9-7|RytwbZ z^Ug1P_@f`uu3DO=A?8G%5o?+%cJ9W-pIF}ITg4c;TgY02O+T5D;HaHx+ z{&=ck0BGB`?D}geIHrbJu zC)4!&@xQA-W_YijJP-&EFF7Qljf1EMPN34}DM?`;F42Pq`I3!s*G`Q)P_G+L?3cJ; z!54u;CyxEqkjT^vJ4McUc8s6$0*}qxso;C>$tekSb39X=B`FOHad_`(+tvgn#l6=R zhQ!vXFskaHVW(@;Iow5qrj&?FlykwCj1a;|7+vwS<{QW6Fb*3|aZEt#1aJT~-;8q( z(hUcZKrwNv#thCGl`jLC=R@pa7@W+?G@fo>3}t$kn`&O51J<v;& z@XA3t&9pJom}z}q!#Ot-Ul%O+`eKgAGbJ&2XVpsLiMV0_ZV1*fRDpA@EU;Bc&LN|e zvb(S^rmy4AkCo+Iu;8nXIp)wDKVZKGwSR{YIJU)ExN*{mNi;`Ssu!*ym}zRxRQPJ} zciMre<7w)UTCm`CVNQr1>JJ%Ph;zq>!Ug3|Zn=+naYwYJW5P0}`lV6U_!x5zpSgU| zaf9c+vtYrOiSalckIU(?Q|I30`W0ir9T-ca&yL~vrVuA^n-JYa$fg|_%0w*nz!tn_ z93#Ge5!V{8I}dy^fE1t4se8HMgvpF@N;BRy)oiMD$H(jYS`ua7@WsSk@b$*A2*uQc ztC-gA`{M=UhdAgM(~OnLhqgD#5ln@5Zm~S}=8iEI)&&c`Y@Awqp3-W!nZHxPoc(?= zaaEPoYQ?s@SwaP7Ox$UT%rx|(sza{mZJ2Wo9sBpGV+$61(U=>X)6ZT7V~f){XHM0k zl%}a?r$!zv;E^VzQ3US;8y}UI$)9gO11hSW~ub%WAda^74|LGi}=r+B27JDhCJA zPz*cceRK3)g9e?8-yC%u9rM6W%;Wo@ngGihbiwPut7y-I%6v1zTI)flln5c1Z$-0h zVlI|YQbkBaiSZUE(QTa=o42ZE+w=)JVN6IkcK&S(@40I%SnyTEcs*Iib>H`cM|RMh z*;33Lj@j)Z5W0s7Xl=;wT7_rW#{BrKbIOF6!(!epc-@$W|E9Yo+~xdnoHIt-$*=CL zu#bdz#ObVWwVKA)+xd0qgNO=q4Sf}i8AS^gybgSs5ri7~sHU(R3ML$BOFsVTy#-Xu z-`H7n%)~u7?+#`z>G^jFwd}pbC%?L2!54;8ar)cH2vhSG_L_6N4t36vHKUqwex~?=DoxYSr*8IM2Lf6b zyyL9}Cs(tV(Z8pin$Ae~H5-<7=z`aQxiHDxvD>aOB_7oC55tT~&WWu13YyM2P{nZv zF76yxc6_t(>v)x0Z**+^c+Ac}_P1cc>%uV#>h#!@MRzPx0sHXE92Zy78{wH+r0A6Y z<)n!_7S1`9KE}8*!Xj)7zAl*4meXT*wd#&XB1(ZUx1RvA>QJKgRKbLMJBjAZ*6I7j zOkMC*$DHyRe>Ocfe*Z;{Z$)v=pUh^tHMViAQRCU-zVV|43%&}NQd;MZP5&N#vx#Qb zeTDfDj_b)+HgV@Vc?^pHFZin9lr}sTLYbq(PH}9E3xdeJ5<4ZJch;ce_cHnHE)Bm8 zi|{V^NnlPpp3<6g%IS`G8vZqeC(AXu?nuQjW)imN)|dAQ=1vFIiNZj8{c9$i7HxzadPc4{zJG!nB}3i^{Zkb$uIaS;}}0+t{l*uvuQY2bfEj~ucLsR z+_3sUgH~_ssfN9ZxAv4EK7@6&V8N^6E*f!bHN5KvVk^zJL{?Qe3B zv2x`2_&Vc;pIkgoZ2GKs+sJ9bg4cmLrE!<~%?I+56%}PF^Qub9k+xmY#rat1txTe6 zoM>_8Echniwk(!YWBmA9^ERB$o1Vi_0i9~Saax#zlhx%Pg5h4egj^PUwQ+CZ6hLcw z+0AR^6D3cMMo51WT5^erF8FE0sWE?4KD`GW}7RS?qZwhXV zWU1R~mfE<^zND&%cPAqkgMilX%5akt8RXSTG)G_rg;IuDuB%*~W6h5wMCFIWHh6dfAfA>mea|DL5CLOc<>+5t!v}Nmu z1+Nox0`{d+S=r}<8aEdzTmEPrY9<==Aq|~6lIF_ZPuWOgj0JhopbNe(c*r=NJ4c+m z+XlYlat*iMyzp`7G-tg|bpnlfw#Urp#WA$tb>nqw&?!W1Jt}uGamV?f_5EDV+Z0W8s`b)u@$FJg(oeV8K@f zwFXVc?iXQdj?>G=8hJ5e7yLA%7OTDQ5^t7C^eO^1%{X5K zbHM`J#Mk?f{bJi4HDQ)}jaY@;xw)rF!ole4PagzDZCDTaHmFPIag|%{!P~ zgWgtY>|{fx)fZ;MFAEm@v?1qg8~IXe;)06D<$U|r4|6P_FG7&U!ntfqxZtNAWBEb` zO5vSN+!|h)YP%c4dIwLgeQjTF=q_74EZTL!*9FH)a~?Y;&SBd=$Y7zSl<=Xsf5P@% zHQimlH>aH!EciO()L6a~m%V;BTgAUu+TCmxa=gIxf&~li0Xe4F6h z!-J~&-RGiXXV7BGF8DfNZs~Q`<=81R_TJ-PZx+HHwt$)VO6dE&{(EI2zM`ea%W23C^kA~9K8xXaKVDtjky^A(YXJSbMJl6$@{UAJBA@2 zwEoTIaNZ~&raDwunP#t?aunTV@x5TdHxc8SLKk(xA zeLovw8B6=LF!k6uG#2ptqTX{6&;_ppuTql;7m7S|I*?m$$y zONivl79J}|wwSpKzS_8}3cB0(6zA?};*M(xjd3iI`&cpR1q*(facU_zhkGS#Pv0M? z>4OvERgZeDm9AOUF>_=i2)B zcy8Q+1z$8ClFf3TRoGo37q{-PJ!S$`C(&5ora}mNhj9(X%n9^;FjNCv)}RZ%#(0PZ zy)_P6h4WbPup1YikQByV-1}neAR~Qo?P##03k!D0~swEOop-IJ>1#W^YY5t0e&QEz(?(i{?btg!LYk%xc4?q=exb zi+nEln&B=2I;(u{KxijS^gfz&IQI_w7d=Qo=Wci( zA=QalT<__eL(-x`7ksrbHH9By=2j}8aGI!KTR&vIAvAXtPixrCMe=PJN~kQ3p#|R% z+{H;c{*D_$o407toRWEy6hs9Nh&W=3`&mLE+ZIizE1?zDvJFJ0^7a+LIR+6|1+DK7 z#eUAYq)SDz1z&NPOq4NSLXIL@n0@=o35Vy5&Dlx?1SgJD`pJrhDKt1#1ksFhp2mAp z*CSHGD#d@3QU(#67c?s=r(s()FCOoMd8SGuH3M3=TjNFyX{>c~&Y(2Txkn%o*onxc zh`V;q;hkT5-&{X=@|Jb!Ht)04Nub`#4xU<=D~gCKk9i+clO4|-B5E(B8#?Q;Hy{CH~S}jLOBWi=hsFdTSh%%k{htKS1r|eL0 zf0Xk_t+Qt`dS5pY60w`eeT^wmoP>i^u4&EYxha1pVe-VW{clq5S$B}HrYaent9%0M zWp#Sm77w*RSQYO2%P0D-Kia(j5Sj)TJVc9ab}`~|Mw}GMS8{o{;ym>s*E~0d*}>Ha ztm#q(&Gj=yk7#l&{~_Q*^W9B&^4+}xR-E{Q0eNVK-*?SAn!!$drwYO#L?WZpj-5Y0 zd)}{I$F8lT@6DYzJ$CB5_jzVt7lY=0oRi&XX;WMI9VN@hL6W(ZlQ2TMwU& zv}NTvj}sE?v(rMT?)W!OKL1ft^3X8!V7zG2qN)@@m>0BDp*$s#4#w5Z*ybE^s?XLi z-Na}vMhb_;^uRRaFoBQe#slXmIxvUo7o8Ja6F^{hN*nkpef@_w6+fOtjZ@Le`?3SFXA!z4T zS|$5Ig7M~VIXB2y3g$@W320}=?1(-8|t3sXC5hU+jx^Oc@}l$eW*k2U-jR%UJ(Q(5fQ4EJVcBgF^)~Efj!GYRxRJ`yfz?%=65faMlR3La&XDaXBnktpwnxX4&AwFtA|=be zYQXv;`@@-h!x9;EW9^U1!Dpj8uy+s@YX?T!}QS_+OW5*rP*ef6nk$tW4`18vjNwk@l6MH6gnee&5y z%t4Bc+yak*cY$vM-vvGZ-YLgdvuA%fP$=UGdSF-nddvo?)6jwiUoM(%~n9x2%KzG17 zCZw0ZZY-d2^aU`R`#C0@_f^*m7JMC1Ew$?Bh#dMoroJY@WTOhDhvJ32zkpVO-(tdf z&PYJ(dT%%S@^!g!c)-mTEciO(F3YP!_xIu7L+@E9gz6aG{r^?_rcXIqupR&a002ov JPDHLkV1g)}w-^8b literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Cart_sg.png b/genplus-gx/gx/images/Cart_sg.png new file mode 100644 index 0000000000000000000000000000000000000000..d52bc23007a203de861e35940a004426ff801c16 GIT binary patch literal 34509 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Crosshair_p2.png b/genplus-gx/gx/images/Crosshair_p2.png new file mode 100644 index 0000000000000000000000000000000000000000..c942c11716a8a7ea610070bc68d7d265a9db642a GIT binary patch literal 1651 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 H`~Cj|J28!2 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Ctrl_activator.png b/genplus-gx/gx/images/Ctrl_activator.png new file mode 100644 index 0000000000000000000000000000000000000000..b72cebca88bfb6255cf8aa1ecf302f52cce17ac5 GIT binary patch literal 2602 zcmcIm`9BkkAD?q$u3?hMOfg54qjIx`QI5zlk2Ay+W9E9WHs>5UGH3LRbtw0uLRjc| zcnXsyx!NP*Ax5s1qp#;3CH%h}OZTvS06004;Fp;0bJj6Q-h zNcd=XgzC2(kzh2^?i%Q5l0ZR}BP|k%#zX@EqU-;G4_R+ec65XhtUU>?xEqAH0DLgO zAs`Ts3l9#$2Ec5v_~1Ak{$@1H!Lzea^VE@7?mzD(d~g5(i;I9=!-fX~&Kl_I8R?!i zqGp7c9VHO$P*&ICD_1MAx4b=|f8EA?n+Q}_QNt>XKJ7OM249vTJY?~=fkkVB?O;eG ziSk=E4GC`qZ17nr_QO@4zN|s73#s|l$f>ZeLc+jL!pA{A(m+k=mN(e)sMaZQG0mrvJ-cxGj7dn@%D((?(F8Qn73aoe^_IilpRWcnrPT8>M7>UP@Qh# z7baP8_&KBzKmw35~u)VZ|-&^PXQXXbNNXx!vESHUhJo;*uzIzu*#q{4y2gXJ~a zS?0Qo6;LhEaVkoCGy-Obd~i+RFS3Qe2w!LY47QITP0(7m@>g2F!8ui+8e3juIoOzL zcugS2om(@b#TWgJm^EPxud@i+O@#{Ad}k7AV4hNQW?4Opn|2PG@|`J1gBnu?hM6a~Ywe3sLriB`O zEM6p=lt^--K@!EYC4r-88>XYb$vQvF!k6#SaU%nbB*8a5r(=8M90Vbv%RRP?!y;M6 zd(iKlG0)}hyc3}vD?fnGpVtK_G09o~>V2sds31wI3&lIiJg&^VBS%1L72T%InhjXP+`aJR|s0Pw1H)#q2=U0XJg4 zEjeMp16X*%%%bS7uPT-FxyBj`xhVKbGQAi=l_8i^JaME?xMrq!KJ}ZWP2`P-=M-8) z$+`uUAu>%tmS#-)(O<_l8*mEI%2PQIc829UUrZ=uG~>ZukNo%@tL0lIdFSbZuu$*Y-z9RhJ zoPpwO3YCar4W*W{g~Gt&Pc4X zsIL;Uv$2AwpToAiuz~+7Rq?eC9#zVI!klsr!^=A)G|{Z*qxO9)x{o ztH{!QpT|njZU3B7e>~D!Ex|jrj%j_QRsBihfqt*+lrmji5%>}rkzDg6*AP+O^UhcU z&e(zXG}?B4X&Cs4-20~-zwQnRDMlhUImze6J*rz{b&FzdW4X%ZU z`mba)1WQzOb%)^}UDs>Be;VQOy+Gq*h^;Q8CIQ_}yl$avxrWK1yb^o`@ysfbW?RzP zCiw&Ra^{d}+A)ulhd=FZ_UoSaZYAQZt2wcp7<9O&@^G?!!*swesLY{L=zM7nun2rrahhD;Lg8ONj#}0WvaY+5VL1yo zc}m$dsY0M~--g{S3ws_ZqEMI#f#_CabY2buT2613^M_>pVdrBx-Yhy)0sQ6--UplY zo`gN8dNefXQ}%y^)w7^U?x_TEXxU9Y)^=*V)@mdqs0pHwhc3b!LZpH|2gvr zox@%s3>(reteUJ&r}_4+whC;?B^UW{1-d z{P@^Gsyh&Vvvjb68say%2PTEQld@@}Z7((O)Jb=S+ikeXI3!uvKYf?jBl14grgpxI zE8I~P?O@|ux=S2GBm-pYhky4kDs15ob^0J8uqDO%T6t4qK0UT78Zb0StZ#6q^(873 zc`t^HK8l+LCg<&+gihR*rxJ?-`KXuz!|9a6!=?h*Y1(MolyXEoH!hL;BA%Q@~C*g5i-HqjAPK$whB1-?;wqQYiRQ*myVB|`Zn#Rlev3%PRsA+2KeQ4 z%D6v$p{vJ2aS5mC)j&^4K1?s4*KvJNKym$&(H_iqki-~C>=9xby*LSR*SY)`!ahIU z9Tm|uIGHNkA@%dP^?iqN+q$7zs8z>MVox|VuYxRe<4{XRGcdyY1< zynAYG8`G7?=m>YmX|&wS9ao#(J0s`nCH>+;+Jwu_%xr&`+=ERQ(l3GQ0SBOF=X#r? Pt_HBPc0@HI{Zsx2&xWfm literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Ctrl_config.png b/genplus-gx/gx/images/Ctrl_config.png new file mode 100644 index 0000000000000000000000000000000000000000..1d6e1c4326667c8138d62a10648295d14b1432db GIT binary patch literal 635 zcmV->0)+jEP)>~5x{kP!fVxfa5Q`d1pdZ| z-7dAj5iCXEyQYCpBCr=X@GB*JD}f7mfkpgifJ?mZ3U3p*6#<52S+&4)j+ns70JMbP z5rNAo;G+ay8RqmHPOJ9x8oq-0oC42qzR~V#An--Y+MYrn76rZ=ZZcEle49Yq8_lc! z$(E?8(B72<%hk`YJx+wlTNZR04I(rG~}?itRq0{{v&= V=lW-qU%&tW002ovPDHLkV1fu~4Z{Ec literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Ctrl_gamepad_md.png b/genplus-gx/gx/images/Ctrl_gamepad_md.png new file mode 100644 index 0000000000000000000000000000000000000000..298b3520dca03819390eb886571a84f623b50386 GIT binary patch literal 4938 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 WZ;LHrmM(8u0AqcNTTQx%$NvX{eMt@g literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Ctrl_gamepad_ms.png b/genplus-gx/gx/images/Ctrl_gamepad_ms.png new file mode 100644 index 0000000000000000000000000000000000000000..4428f41bec6149c6cf9dcd8bbd020e23eb7ab611 GIT binary patch literal 4286 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 UnwYYS{{w)YmXT&H*dgx!0Oe41$p8QV literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Ctrl_justifiers.png b/genplus-gx/gx/images/Ctrl_justifiers.png new file mode 100644 index 0000000000000000000000000000000000000000..a2bee99f939617fb91bf605c1f3e57cc97f4b0db GIT binary patch literal 4600 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Ctrl_lightphaser.png b/genplus-gx/gx/images/Ctrl_lightphaser.png new file mode 100644 index 0000000000000000000000000000000000000000..ebb223dce1a3b8d4ab0bc813dd402b6140538d56 GIT binary patch literal 3890 zcmb7Hi96Jf^MCJQcf+zIxsTPcK8~cVoVD0>L`p=?D7Rg#YlYZ#geXfYR}=}!l_hd* z$<^U(k#lpD9E*^3l%MaP@SEqEnP+BR^UOT+%=64MiI>fdkh~JS001COjPY0Y^|gI= zK*09pJTw5kub_eYCRT`jia@v~?Ar(Yjco$~fOqA84AOsv&DeL!1re?VS^BvLQCtGt zfQv3S1N=yCu3j#3hF$?~6u$tUK)H+88dCo|vX2%0AJ!ni%_Ydo&sWaMi{u8VVNa-Q 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Ctrl_none.png b/genplus-gx/gx/images/Ctrl_none.png new file mode 100644 index 0000000000000000000000000000000000000000..71ef75ee047f18f6ebde36d5ec90b2c11d62b90f GIT binary patch literal 2227 zcmbVO`#aN*AAQedG|W&ej42|Qm`Kd!6OvU(H$;rNe#z!O@nI`MR${16jdH&x3MIu# z#zGUtMp(JzGHr58CLf=F;rn`?^E%IYJ?A;k`SF!;#`%N{L>U4AfDFdb{_GAL?Z8nI zytC`0V)b@NEXo#hUUFv=CH>QP^e%#kh4s-9|2_@`z2gVjV-`#NoNbmPh{DuO;t-l9v^SFYti5c7{qqm`xl zE1Jvar@gESsKW)#O(qo(X`o%KP1Mp;WE>&{;NnTpUeVE)M^KJurW* zRvA9tyw})X%{RcFLDqp}K~h>=V}X%ix4>6J4-~_-AUw!zloze0LkQxPApE}3wVS_P zlP^GZsf)qlC2w#J&WgZPkRH_XV3{y~A6Ltb~rd+0>t=Q*>4`9?8+%oZMeD4)C;z~g^f&zN$qfHta+OR!SpLO@9UL<>x{~jqi zg-J%Rr7XQcY7*nxhJ8IM{I24G`jK`WyHL6m{UTS2u6A%+MG%L5PI)5wP}Evi)<-0% zJRUa?kw#y<6IVjw(cuKdFC;-pG58S3P>S7mKk9|-(c4RN1@z33`QuK(|C3OSR~Stq zxviMHFb4B2Ez@0VtD4Oz)gKl#C|8|}URu}qXLnnT<(?aAj77ZgB(d_!W+&$@!LKe~ zcNWzq`!JDagc?P(1g)!bJ%^Mq1&8f48-#Z{m<-3%zAsT~bUueub=-sNP!-57I(j^^ z0Sm#unogwf{Tfz5MJmJLxeYWU-Oh0AamZcqx&tMHD5u5K4}V*|C#Ek_p%RUG`XYJE z52N>oRJz<75JcE7V}X>-S626OTu;pf9&B8bh2Ar8+B{_`Ud1C_bB?bhxWCc@WvOWK zD7PdNGuEUj(P5vJ4dS=e!oE9;8o0nJn&?4OOsO$T266E-Io% zrk^zrTm3FIiAwY8$eBOF%^GL|VRsSbOZrrMWBH)cxXs=xxMzQmS?#Sx&krlIWe3x`fdm#3f6 zv&gboxnK{{aKi%g3f+u+qFX0>pahf%LDSHt?Nz9rpTYw7cNTiBW&j{mAVSd+ICq^G zK3{x%zpSMWY1zM#oe?mjtoV(AQeLATFMjP_K5=V_n8yp#_d7Nft54t^XiYXJc{bQ> zmky1KVbwC{;(YhU7E+EVO@H17g6g}uyRMu8)2PoMc189O1}4%F7VXBL%7*c+*V%{q zm~6M4rY+7_XG&nZc8R;Ey#Tfb%fI*MTIZK)MH?xa$e)z5pK?z#IWd%rEK%*oJ3iyW zq?M=Ai5HPV@AGn`m#PtRzmzzShgm&o^}!qapGvny&{gSC?1Gus?2bNNhfGthtn%|y z4o|3vmj=f3(y`tQW?}IV>Q5c^BhC@(X!nyeV%Xh^^KU64PnY^~bvR8p1;A*823X%( zin-t*jTNrg4I?xEDim#|j%}(i*^$LKZ4Y8twrh9Hr*7Neg9p)5Bn8bC^4eiwX0H9c zDBksN63^QC=j*&ge0R4z2lp@w^DOSA_n!^UY6VVJXyE?Ka{rb}&ICDzcjp!4i-hpv zY*)9=q<4+x#4_v2#tD0Mw{olNccUzRWeznja-^YZ*t)RsFtl6u*tEp@ueDd)Sd+81r|L9)AR!d2X9S?pC%Ne4STv}}0` z?*N^z97?{guihvc+;pj6WWp#X%NBoh4y1GGDsVGjjZ|DF@hJHJl1}XkX|UUK3-*+T zx@If7iID=1<~q8_c6qc}AE!FcMpq7^7`T@BRrsX+Q$`Z+!Zs5=87AqgoX}Z8JaAcuA!e`j_1AOmRM$;gN!fSshmJFHwnTjfk&dby^ZA~5cfL+9 zPj8IE2h*p=VQ))N41UaP!g;WII?6c#C;9ab2_aV4-S>~QhU(JT+`hvo#-y3?QNuBS z_AbfvAw)xUuAd)$52JEC%>$b?I~fT}s9GaP`YMeDSfmh4t5^)UHeT$}s7Bk(k43j# ztMV6~Fu4{FI%VKaBgHG9OP@UG^)p$G{0YX9RnF)zh`K388SxtpUh61|pTai_KqE!@ zTOwtNDEWq^fMV>osHMWcqnX>cY};mwU~k3t26&Z=`8gn2xbcFMztPOy1jDiY9|~c% zf6DGGqZrF$VTlIuSeuq^q@fd5?i;dsEUjVIm@~~)z@4t*V9G-(`dxX+N-y6pBzbD3 n!0OlM=247uPfl^Rk=x>G`r%Fa=f73&JPiQmxU+qoE%w^K$tfxQ literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Ctrl_pad3b.png b/genplus-gx/gx/images/Ctrl_pad3b.png new file mode 100644 index 0000000000000000000000000000000000000000..8f36c1aaeff872e3ba3340e06c258cd10a2e6719 GIT binary patch literal 1842 zcmV-22hI42P)=P9p$ID2phQHJ2dJ8$CI&GkYP`G{AB=y4 zkH+{cF)@?+4IW3@+c#_FEbM|F@ z>s#Mid++1C_blad&H*?e4b%YDKn`dH^1uv`Qg^Q(Km-f|Q@~aA^GmjWvjd!SDIg29 z0BeAIf%}1VK!ZT%m19r}>0$u@L1Mb%A zNi3XWSg0K^A|MTzTv7rQv|A9!BF6l1Vtgggq_!qZT4~@4@DZ>FIJ;OXZV}KlupM|y zcd&5xW8n@A78C4b#b${(!HW7HuE6%ZoIEQh8-P*Gl?7H|`H==r0dE8Qy!SKL02bJn zfZbTQMu0vU9|F3ugxjbI(cKGBO3wkTPqcfrJAuB8MJuoQDltja0Jj4xfM(fv6L>dB zBucRGB=EilT>;Jk6Z%bQ@-E;uV7=Z=2vmVM{7JThbW-Y z1>OP1oO64;_r;*$W=!y#iFKCJMCavo9ndSljbb0M6T%(pbC5>37X+qEfGe>|QKLCC zK$~pMVO8k}mb~p)gm-%Hk4CDmy99PZOy+=bvDhdODLrQddIk&a6sGT4pi0aX1vIUG z<8r2eAK|9CfVI2$7 zG7^9uEc~MiRV!8}$BDIC6uXB7eq7+*P+L*&8U!{i#)=}SUnHFo+iNg6HS0NxNhFlb z3ZOYu2}fKjYvk1^mVgCKR8PFZ&8uyt*c-v*)C{b}5(na?J1^kVy0>WFIn5K~SdQgK zzZ`57F!=; z-~jL_R!>L7@^&%Umk4X8+FP&{XhJMqAufBNtc86<23y@)HEs-(+??!Wh&3Ko(v@5`>;_Omt$ZO$;j|Ig|!VUg>9N^ z4wF_Hrte0PRwv*o;8T&ZV0*b7_!xKsTX}|MG_Ap90<=Pt9>U~uSrHf#@F6i3 zq;+6>g91>v=7eCIt8#3|w*@OxQ@{h*@oR>70~MT332Y8{9oQR=*C`fWhp}CL8J5L4 z;zMKwmbLwI<_z#XcK(|3-p^g{)sX%ynZLO-7>uxJS>Q0AD7* z1*9}-V7Ul<27Do)t1%sxh<8sBCWHMz|583I=%{l@#8hAi;ET4tKOaK4?07*qoM6N<$f?wo6QUCw| literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Ctrl_pad6b.png b/genplus-gx/gx/images/Ctrl_pad6b.png new file mode 100644 index 0000000000000000000000000000000000000000..f08bcff0615e09cc7b168d384523768737025f2e GIT binary patch literal 1777 zcmV&dq z=l~W7d;!P{bQYKb&H`tEUf>|G4>$n~nc39;0yu=w0Ne@O4csNL1>geC>=-ZsT*TRq zfa`%qje4L?U=IMl0N(?9&1^hn3xMhP<^(u|kP*lyfO}$2^HCIm(T6v%w_!#)a%tmKo`5ys?5Y_>20{2VVexM&10S538=)q$$y1NID z*;)Z#DnLcx2EE55Qv~K~bOJYOW7~lj&8+tdOtS$FA#4QR0~P_l3TO#;Wd=A292WQ^ zl4;WN93Bo4cn5F`@S9{eXcO1#eM&kTf%CvUz%F2`nVk@x*#U__VFe9BUzzZRS9cH%E%q|a!5W)uFT|9Bx@ml+bK-7uNs=y+dSbsAD*^P(C z6y8v7#;eClU@!2RJoC0Tv=2|#7ChAI^&XbZ<-l%Wvzc9tj1fY}0uST$v?}(_;K`Q9 zlc*LL!W)H2X_w~L;$f1(6K6njHNbk!<$-2-t5^Cq0k>)M(K90gUIvZ>8-WMFvpGIX z}CHwaQ9g*P-9%EG*3sO3t#PtJGP!c1xGSo~`K??fTC%v&nPY6JbjQ2^l zMY>J`holo>C~4&7#ZF*FIwYd&3tBLamzD@Hw%OP?24%b|b}K1w#A9Suo3Bb=A4z!R zQa8O>H541d8b9|R;RqtC|f(V!Rtgs@lur_DJ?}U%Hc)4l#&_7n?pBA2||G4`CvjL{d+Ps zKM!~DQ2~t`ihAJ!_!iHrEFN-MU@!tUyd<^au8PUgFXI`>6!2J%>>);qQW!%b zHw|p;XyYPc5uP)>`c{z5kn+lEk#hjA5a)od2)F`#2fV5s4x|_w*L*sW3V8h0rPhyV zlvCf3e1;@943EnUUKJ*B??vxa@Sb3JhZ`06UBJ;C_yIYDum|`C?{>W@hGOpy0@#Mf z`bCm^+5pLoBi7bfHL@fJ{AP^;9%`-H#0VbOaqX1WHsEc%7WmA}#-^VoZUw%SyN+vN zS!~36nc+8%E`gnp%os^S7?JTZNlA8G)??J_X(|v+5P+;Sj=; zz&ipN%T>=4801AZ$>#mLJGyMbrS>n#U{n~(RyTgj7{^245MJ1O&8)&4pAbU5K;NM^c-*eSy-*{b&bJJY zy(-S=Af907|IL4lX0WvwXE@%jNAa^qubEY&+!Y7-8I;91HJJ7fg8%rLtF6BQJ_Sy~ TvTm|Q00000NkvXXu0mjf;9eAJ literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Ctrl_paddle.png b/genplus-gx/gx/images/Ctrl_paddle.png new file mode 100644 index 0000000000000000000000000000000000000000..45f5146a0bca69fa9d9fc5307bd67e0109f0cb31 GIT binary patch literal 4795 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 I`mPWD4+Y*bC;$Ke literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Ctrl_teamplayer.png b/genplus-gx/gx/images/Ctrl_teamplayer.png new file mode 100644 index 0000000000000000000000000000000000000000..ab8706c41facb8abbb8d1a9248e82e7300b299cb GIT binary patch literal 5929 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Frame_s1_title.png b/genplus-gx/gx/images/Frame_s1_title.png new file mode 100644 index 0000000000000000000000000000000000000000..1022718075b271f831053a7dcc44eb3994a75e18 GIT binary patch literal 3510 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 V49(V&<^G!hOH*4k#n|h?{{e6Hkpch! literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Frame_s2.png b/genplus-gx/gx/images/Frame_s2.png new file mode 100644 index 0000000000000000000000000000000000000000..191c6742a6be89568e7b175ea6b336a5f5e9f9c5 GIT binary patch literal 3890 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 KbE4VZzy1sT4tCT4 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Frame_s2_title.png b/genplus-gx/gx/images/Frame_s2_title.png new file mode 100644 index 0000000000000000000000000000000000000000..05c8b237ae8cd31672d42878f53786457a0a2c74 GIT binary patch literal 2285 zcmbVOi$Bxv7yoRASs1YrVST$`(&o#EG3Js>2vKf@W+I_Bm*sA`q>I~EjcTsBOD;oM zWF(4E6s>Cp9 zO(p@h-b8Y6Aj!wy8+pQ?ObQPs2T+iw|yhecb}Rzvsr&s%2-sJ z#vf*`^)q_9H!fUIn5fAp)mzGrvORp4NLJwA-Tb-W&sNwa&i~LClre>x)g897@=?;k zYve{A-K{*@kf{?ZdG=}DzO3EgSvK|gUB~rzPjauVdzgM#wyfIP|GAm(+B3Ly2+4s^Q-hT$w0D}1l~t)S_6}eTm6Xq{i)5l4px*a{mkOk7;)3CQd9fmEMw2`XyqG=E7#l)am#nI0$9_Xjh zH{?(Hsf>i2eLOEQ|NXiruS#Bqvy7c4_O91l{s?AM6eB0w7~h?z-`D21-o}xq*u1-s z8Xp=F0zLFt!xV=UNLpmUbTsAxeEV1C{V5Ke9-VTeE$3EEm`!6|Cg;I;T!Y^oKP%9U!-l`VYd*D} zJVb>XZU;OL`r2}$%Od3~R`)LYR%rD8Yde0TvkNUy;z2dJlO!ZD$2cK$NzSc$r(U9G zjTX%k7MeJ^z?6Dk)lyb#hOgu9yTa#e9S@-YH~u=H%SdD2`FF--un#K?Pn(h7lUKmV z9~Vphm{G4T30K~nI*jc(yJ!$Wxv-&D&PX1&y7(`eEmTvbKBM6!ZtRSJ$`han1bhBg za3b$XOuB}f3uUPVE~)HsZR}U*ni11?WirYVjbA zIoP*w-cnrRy1$z-6lARmc+<@IMEtc43}?=MF#(^zWyIJo8g$+`)k*YI)MHH;v+JLQ z4fX9g{n4W_*;V<77P~jQO-|_Cpm&(ho}rJ&5=D8Q{^pga{_V)Ic#V|FZsn%HYe8~H z;!DS|a~!RM``;_fnD?BS4+v7nM@)#%a!QnsoQ_2z3EJ~SLMRS zwEfYK4NXsC$3r=YkV2(vv*jVW;A^k~u>%wab`?Ht{9u#%dr75+K~~ zJwwOM*kLe|%I&}Hj8v)PhfhSIluWtZpAe$3+_w!yVU5{!({+Zu>t3nZP>^NuV4EXR z3Z)i*SN&cG2RqiYva-6}!eVXIu3yyYJOD5IF}eCmwdbj8O)Uq9aoM>}JdCC|iA%P-WZ~X#g2|6Bga$*TA%tqNibAlxL| zL0*;HRc?DCcDgRIm3-x&;cr=U&mOY^_V#Lw4Q+bc;K0S_Q>5<4SJo-F~hnF97KKtQ8z zYi;B4N8Al~1ECwbz9ojEA-h8pLBJrmrpSBm7nhjp+x2%|cs%IQhXMBZi_<)})KFCK zg+Hx|G~^)IT1;F;q+oVF`pxFG51+|y%X8BV1cFrWs~tN+(6(j#l>1BKZipoY5*tB* zyJB`qCa`IS=f5@4`cf0PNts1HUYL~da45|NEq8r+25o#nl~7UiPTz>4Pf1$x2zhEx*6~#0%f4$1g{5T?v?2GkHMneCU$j@qLiH;?^UkW<5)F82s zF!jA(1iGzr3)vl#pefRIikWFSdvvN)LFd?FU9sSQ=zjDz0HGkbtFwxp0XTX~DBZev zVWqBUslZ`kV@gx-6nVt5!nU??WQv(JZ}?zr;J9cJ!pC7HbWw z9{Ss4L@E^mv@PQT{a?LY;|a>$zI`VZ1W;k}ou@8JL-?`dzm)B$G06BGAs8W@1`>w< q-!^_??-~;7s5-8wL_-R9>;UY_9IlA+TNS~$0a%&anN^#3(f$X4r#oZ- literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Frame_s3.png b/genplus-gx/gx/images/Frame_s3.png new file mode 100644 index 0000000000000000000000000000000000000000..c12f11c9ddfd5214fc7b39cc9c7e5926fa59a0c8 GIT binary patch literal 4447 zcmeHLi8mWc7muP!saBP~YEWXYr7D)Hy_QfRA@XQ#UoFKW_E?%ys;f1q+KZr}L9yrf8iO5Sg1&-2HosSI5KHh4+kt>j9P);B8~=DSEt7Z(X^XQ1q5={Z%E+9B>2T`Tz$S+H5M9O z8X(1NWXDHX{K#gCObr+ew8T9B-GcdTIJFoOc6$urA9k@@kn=VVq;yYtMIzBXgj%PD zM_?zQ7eyAG6Qa$`%zl zxjFp-=E9G{!{fvEUxHt8d_OQcAW_69RdqEaEDTSv6~({C-2|6i0PE`F@hu0D#fFJa z;*uwnFJ1Cb!N92|S1niqK7pa5raP;pWyTn|GYmHJH;VHhtqr}-p1nhknKOc@(;wjt z?nxQJtFJ?qu5;D4H+c>I$j|>nRM=#1jl4OfDIf40vs2r@Ieg2QGUy#x&uowg%tyI2I3S0rzANEOPS5es?+S zd_u{#o`n(;nNl=T`eyir`p?K_;*Jmd2++YZGdruZo0L_cWo+Hs3)zso)p0o{ev-q~ zM;#2&uopmJRc+{F1!75`GB6^uyi}gz*|Ph|PNVf#{|pws=x|apXf@A}+NW?n^z#y} zHcz7^=1o00q*YrxX#?x4Cc$Rd|H!|zo^}aul@%5Uk9nDn z&S9^}9^7F}&yeC3q0MV!g-sz59tRfn7o-ZI-LpL3czt~MqJ}37TD=%2_K0IsaqLP- z&XFj#Mj>TR#3@-WFKpxOqva>ba~Xq&BAz6Dx%hqe*n^<=-d%oRCrd!O*U-l=;Q19n zxA%8{4?UKN`z480RY3GgDUx5L#|n;lXO?RWdr(?p)`~Sr%tyK*<3kWpUQ>rFTvr}; zCp5#J=Uw*vP0h|Qx`e+ysfAF3+gSrEqm#wmt>mqX&|_^UB?7wB-HVx80ET$7fGE}7 zWZzKz9w#|BgS}Sf2~o|~yNSRCMy0}pK2E-k31HLCeqNl|nRrfsSplFu8%FU6C#PB& z_Hb~v(8-gc3mrRg^>Q-6ZLl&uEGK$g2>4DnVsWu(|iF!n>NrVgG;Eh_pjHzf& zMDL&W#oB|c4?y(wt-ODLTxD5EyIi`*)1Vxx*eyuR?`uH7ipRZ-)_e~>$1+r3B~52?4QNjnf_GxIc`EA$FF_Q`p^_EdDn5Y zQ^OboFtTTN2koHtm=QB|O*G@9oiPtqHfaw;RHnnua;}C3C(pgP)da;lN53W+pgt9J z9zA~%&C2Ip%Bpf`w;k(yIdN@!JZK{uX(OO;u2-!xFm^zR=-$c?BBWbo^q*RrI3V^* z>*5NbKvRc?iqO1{?e+ZjkdA{F0WB@4%h|IA-<9FwXbph2 z0aMy^Fyjani$}u1_vpg?9-bz4@c|8Qu14Q55T= zWC_RpEzTGVSEy8``}Imd>K;7cJ#vS;xIlqCOFHLr5f=>P;$PuFu@+RNdxgrI^t!>Y zi%OZNWfJ-i(>(9)m9*1hS^;tI>O4cno@@_5a>X@KIoK}iB%D5^U4h8=?%i=lU0u+t zOh9A-r6%){Fzbbhu^^qI3|SZG6$F7k8uIfOI=doh82^*6tZQrPM}wR0InX_R>{+Xr zd0gQaXOnK3rdOn8a|(i;ovG0FfPyo<1~PQ}#5+C5Vt2lOkeTy}FP23)-ii!uRUAe*YDY5SIvw zNtwF=1UlLPTCKXxSF~=5izU{FT_mev&5wNp$D9&O{6ky}a8(%u@Z<9IagBLtc8NzT z+5DK-@f5yJVWIys{NE4%Yw?getB&Ipcs@dM}^0%#2 zV!yUekEeN~o;b9VAWY znIL^0p0WnAG2tNo$@~87$(fmOmaysZvuz2SY->$5D+`7!*VTfaf;oxP;7sj`)3<+hpwLM+q zXQ0AJZ!OL*c0i$pTL{B1D#@w@u#-46BobM=>$i~<5_bX+m$cukPYdk=+uGi|+q(RD zb0Ayq8W^iOXXO9h(*u}mQ-gKhYz?uKWo|av2HroIpK@UTCQr2)8y?+WtoWqX%7y`! z&iD-!RC!zU4^6a0a2z~XI(C7XNGmX1gBEyB1?K{x3-snj?z2+1(H;d6%UyZ{#oLbe zZWncYXCja$rvOu4={Q(L|5(wFtBg59i5t?z#Z7(_{#B+TFxJvpeRHS|HvI*xa^0qW zwKaYAJ@*(}AC5|*fc}iWpsGGvOHfARU$n`c453cFp_i~9hZ{})%awTvp3PqDHcyIF zg_Y&!*V^}}JyJM7NL~FZ=3L_0j@()ObkYOcoSfbLvkt7WbF-SPe=#00U|51E-Hj9g z=trbo;KH^-1H@*BA$hBbj9EAvJ3lOodO}e+_a#26&L#^vdI3a?JP(3|U#!l<#Xum~ zBvB?KtC~=XSr_vc5@Xh*v;k;eO44&2h}zOBsjGA}>B{>Rm7 zRkfhRlKY2xs|y1ON{8BYR+HP7zVwyX`piWxj0v^Jo@#^1Q$sRw(Rm?)*h3qk^cJs) z*GHReoD9~Hf7NBzM)()H3%;YHY*^+ppb(1{1IG@<*q6rTQYe&yjrP5gJv%!)^FU4! ztde9$#BNRJ!R+@p-#1_3rFv)L8twEr2RLzv86;oSn6czgZQmZ}=H!&!a2-X|z28A> zkk$kwAA68!3$cVEgtE3x?)1@0Wa<@cy0#7cF^uksu|xR098%z~9(Wlw z^6@Fs1MJtgRF*6tBK$Bg5aH%lPuSZSX0t4>h5l_bKaU9fE6~~9J=x984SK-245(H# zHuiu(o^mtN(a*27|H5?}S65cl=&#En=f61w;PK;4oX%+xDcu(f^XgNLemj(6`teH3 ztSf<;db;fM2#ORa;fc8rxuEJ!YF1>b8Ft*NH(^H|n&n1+j7RO;hr1d1Pcy)m&GM9gKtY$kp4IT~x3atP|~^pA?PtjLSW)Llt=l;85NHE^F>ZvL_@HY;xEP1(+hANIzUcp&5^R2yzLjf%9n&_SE2FuB7spdAk`4 z%>s~>P{BnqSQeHQX8W|&9`2JPHaCJ`C?Cx8cS>*!>npl@IB;-6YB|~bBe_nLvzhix zd<3RB_@Cl$vP72M`ePNS2hYK5&a0l&3RW~pLXYw%7wkuU9-2z@3Fb9=cMthy(35K` z6&u@R)*$)1Vc8{mF;x~4Tmd3#Dkc;$e=f;Kr=ACOrjvDT-d2cXbgXHO=d$LETqCuW z!iKnZ@{WsUn?Tv7pQHx|E?qHAbZ0BvV)))#8=P)>RJ3;b02-S)&iXrjcFyFCwBe1n zQGA`!9CXzu_DcEE5j6H;dGV;(%2wA;QD;W>cj_50PX_A6j`h;}Q;u&q0*XJwRlqY> SCb%CQ0Ei{@M!mUL(tiO4q6%98 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Frame_throbber.png b/genplus-gx/gx/images/Frame_throbber.png new file mode 100644 index 0000000000000000000000000000000000000000..98d5316fb84ee9c7fc5714a5b0e5775cb5381a86 GIT binary patch literal 2334 zcmV+(3E}pMP)KaYcY?dV{!8ym!P(IWD z#ntC$H{88Dl}eRVS1xH3fMhbcoHM>F2t?v?-xp{**9AiDMD66tUGMEX*jQ>^rPP6h zkT)3TQZA>#Fid0yv-qrk0QJdQY1-7gb^_R4O5KtbVvNNIvEg|hY{!K~2u#DoC&yYa zX+ktsYTfG;N~hDq-xG;MBj-Hf`#v;H+g^NLTpK|Uz-K;O*9D~%mT7`g3#Mhjw5;pu zIlgFQzSkTI$uZk;-E3BEwQc(2Z{I(w_r|q0N}+~^hUryRRhsL%@3^kp?E8Lmd3kvt zgm`{r9_O4%0wC0eq3h5z6_#ltQ4_<^P?i<*EZg5$H#z=}W!Z_t$4^JjwqJSBTN16r)2hsGi=XPA*)&QR8BQuyqUM;{d3=m?$b6u!;70geT-x5d&(cyU> zJkJBA6oz3SpU)$o&qLRBj2ky@ICtb?Or=uSfsBZj@~{FC1jyy{C=@h!t_{u@5|b-& zbtqf7almzJC>##&^*m45wml4!%jJ;GW?@+t^7;IpubKF!Q8_VkyyJY==_OBo7vm#g zxDEmH9L%{liHYMYaOzZg^(__3WHMJ6V}CMDbET@P!|G59_kowhz-##ovuz>jtuWb6w*R>c@shjKnDwLv|*4Eap_B`+DAP5iy z!6nl)hZQMx=e{wDbE!Jn7>`Z(c{p6AKnV0+$rLX2^#1hGh4XhS08mv`)x|lVA%wt} zhWL0W6nb`GU|@D#U0v^((0m!X_IS0mk%%3|e)-YrGuDAZWTT&`3 zD?gHDc}CHh8Drp_!}GjIG#dRBz?88BO4L@rc;v(xoIKruY)(Z%H_&?aJbw7h_oeAm zr)-ls=Z`YR;QKy`pN`{z5CY4x5{C{QdSt9%)BbWa z1q}1=pNWq17cw&E{Ah9CB7`89%b~x&ADK)Bwrv;ItXXq>tbhRE(^IXR9$PpM56)|V zA`3*qG8QhFgGfc0NT*M)R$SM8f-!c{G|icsra@IzXqpCDmhFA}_RU?qc=1^B;IW4n ztpD4tzvJNt=lx>QLvs~E2)Zx#7EYWvx$2GAckGc`TCR1Zv$M0wb={|Px!fdGRnv`) zjl;!#LgZvw{)uUtM}cpySh1EA3NKQ%!dtQ| zRr{WgEB%>wADG*)@@BPedh3YC<5ZHQ6|yYHBuR>K&Sw~g@rkbMqmB!=3)>4;M=HXH zUDum&=4@xIz4KBmnW$OO^Y1=-v;0v&@p$~bP$(2BI(N}1P1BS-&)a&ZK(UGAwzjrk zkoO+^2p=D7!QKNO;@4Yt!lriQ-F^Rj@5cO5E#sVj4**6UWhtegl)|=cVfP*!9Q;bns;W(~SS*NCgqtUfk2VW|pyPbk#;Ydt66B84q{Qbjtj;Z zvbj7&z$HG4RDz zNC>3q$=a9p?f*bZrBW{eXelo*1Lq7{K?k7(zVCwjF7B#}Vq(B9GU%54=QgzWG<7v3SHMFP1B(3Isjz$@8AE>k|j$306`Ea zgi=u3hGh~Mx&g~F(cRsHyXzCfb+g&*cL1Dx;kjoMU0vN!)jS9xqOIfeH#fe#VboFf zrf)yO;qa=r-+ue$L?ZDFrS!hu-rhrN*RI{OY}vBm9L_m7pC~W!q~zmxW|`abNG{_Rl-d?LDyn{VO+{yJV+sZ*SKKwPP19cB8kiAAMH_FgSP> zwKbCvn>4ZT`>n55mQuIm*D<#3ta2S&l$V7d0)~(*F!in~L@Ua~XD3hH@pb9H1`37b zJ$-#wmIndP+*6;#{d4X`G!n_QwVz+UecR~!);Ep+0KefyUOGUa;s5{u07*qoM6N<$ Ef=@zlhX4Qo literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Key_A_gcn.png b/genplus-gx/gx/images/Key_A_gcn.png new file mode 100644 index 0000000000000000000000000000000000000000..d95ade81048460fecd7ed287d0e9cb579ec1591a GIT binary patch literal 1705 zcmV;a23GlrP)!~Y^XI<%tbO>*$tkbqA=Y8E#VLnZ z^N4q1R$sos>YuI?w_}2FA7eB{T99Ws)#)mSA6=ZBSQ_sE=ao`R{}u?t@P(CQE9I## zJaWK zzzYDLQff(SefF#0cq+7!CDSRH&d^RH2!73DxE0e~?-9*Z@kf1bzp+XC#vVc4L+cW) zHM-O|;~1Hbn0s)p0z9ddTJnI$7Zw(h`J;2AhLS8#$#hCuWY~(uSxaZFOV-UOjL{apW2Tz|cIxwCy7Hu@nIgB>c z#v_J1IeTkel&_dPGJzUEsY`DBrODXI2G#K@gVqq`DV%Yj6hSTUqRG&v?d(a<7;}8( z^wA>GF~ed=QYIv2LgrEma&BL}O}Eu$`q%_hM<$tE8E5+B1bfX6>wn%r!~$Rni`5R3 zTbva}=0-~3SYV84)TYB>S|;GYT7xMK;Z($4r^DLo*Xi{JOplGzYHri+wehDtN?o#f zvBli+8LIUP!}k(UfPgJ6)kffeMgUNhC4u!31Z^~BsR?Qxn{T$b^^e=6gN)uEyTlg; z3lfE) zZ?!3+oZap&n>SnZT0;<_K3l^UmhCHTvUY|SD0FHt+F}b!-pvCb_JbgJOc&SpM?;EPQ5`@#Qh5J~qzG15<>P5yRUt=}ty%Dxx+Mk#}+w z3Y}5a@G}p1DNVCz?bVz8WRT&H1?)AuG+%3CJk8ig z>SUdi-FG_ln?vHwgyF3rI?*&1>iD70U}MPOR*YZu(6Oeo+8v5W2)q=CNYnGY-(G(C z%41VU#^u12r-t2_$s=RTj7>1Q*dXs0IOFg=SEL!6-Y z^KJ@@$qiXMqkFx-Q^vXhoD-4e|0@iz}H3OH}|T{r-AdzQ~B)5l$v{JZZaILR&fqf?pu@_bfU?6 zMcKbO=q1~U5+U5b`Q0n?10svS4}h~usU(^R-N=EOtu`uRjU(?CUf#)lof=O>Mt}>z z5AWFWq4_`GmPOzk@G8&)?Ed!l&&~mh_hS4D#(gIq8_w)*00000NkvXXu0mjf$x1jH literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Key_A_wii.png b/genplus-gx/gx/images/Key_A_wii.png new file mode 100644 index 0000000000000000000000000000000000000000..5cc2a470de86e6e95e2138a6d55e21fa06f1f4a8 GIT binary patch literal 1542 zcmV+h2Ko7kP)YZO@)fWNBhHk}X&9ZiPrn2=pelmVk=0s-TLAc&F8ix?5ym0ny8 zGK$0MgD?IEB9Zk$%nU3GE~4Z`mt@7(JSa^-m-a_8U%JaN;<#PG2z~6yI z*#M-i_g&Mp-vVcvnwlDkO2n1;(Y;+)z{ank&%&K z1&fGyo+nBv5fPc6pO>MbApsN+TUP+|x3;!A4<0<&5NevHSe7LsB1$Q-ZCeV3f|#Z$ zwr$IW3l{`%fd0<}KznU%ZT|M{+Z)1@$)v<$F^R=uGCw~rA|l0NQF6JQq|<3hrBaf~ zWaPw&69VLcb`e4UbQI?fA3of8=FFLOI||_O|+Pagk&)$?@aI*|%>WV`F3Fayd3_+JsUH z$8k_fv9hv4OG^v={rwn*@q?ymQQa_%lbxNN!M?t}4F!org4x+w4jnqg;NT$7o;~C4 z-MfTBA(T>ho>$$o*(?JC14N_I8sLQ9(9m$Yx3_mgxM`Xs5(#$g+C^(?D|`3uB^(ZO z=guAG=jYKh4aaeCT^Gl3ux*=gI7}oG@qj<*zVCPT^z;Na5+svJ9zA-*(W6H(41) zc%H|B0|x*Y9UWz1VFA~5v2B~RwKZ(prdTWz4u>_vFg6851lM)f70k`eF*-U*b8|B{ zZrs4OZA{Z-d3l-I+FIiAID>;N|t*tRTJImFpR~a84r?0P%&6_t@1))%gR4S!_ zpLNG^eo7{jxUP%u`#6q6xm+e5kF&6_!2bRFi9{kSEiF+hm2h1b%d&_>BJAG18^>`- zBodgWiD{bHwoN*nCZEq6z~2mDu23j^-`3U^?C$QywrwoSA{L9G>pGV&U#70EjzXbO zy{(n-eV^B_U-RzWJG#2M@H`J)*LnW@IWsdeB@r3YMP#vDF8^g@WQ1%sODGf~lgY4s z`*u#9I>pYNJIUp8)mE&Op;#=^($Ye2Z!c|aZ7eP>;`=_COopkcDSY1_7Ll|jB50b{ z4*cu<`SXp#!^32=SxnQcmaGC_TU*1jELK-nSzTSNmc_Cxlu`tPLE`Z^)6>%h;5!kS z(*ZU>+SFTWBUr$XlpHfIo@IKR)AqDflG$ z4gY=5e`s%S4>mV9`;kZ_uw}~@&9-e)sg$JCX_e3CjisffGB6B`$p16+|7V0&ep@a9 sZvn?J3^5F&G8SJ0e+HtJMAwV|09(2&Pp;PP8vp|nJl@-$0->8$&r zs-AlT*8dV1V?LGV`4hJuJgAS{{n7m9nNgnA4RKvVRikx-)D^C2*{Ca?xp=`IKl3lU z)-)u%4sz!RwW8oR<5lLOjH6St z#34{C?1>@{Pff>9RmDBVn8j!?7~HckKi}RmH9bs<5?4$xRfX0K&USAQ{xXLqtEN!bX2LY1J3L1|T)jUol6 z6989LAO?aUep~;}v9Y<%N-^dWQO3J`&r(^l9t`KRDNeYauNLbZ37!w+(*zYNRbmW{ z3bH-HNgT)J%jYlf&gof95X4)8C}J(;=9sn3HFjmw?2(A1?wAgNnKi?rjtOk?PE@rN`zXKT7U`)9m?%xW$95e}*YSs9 z!b@Glb#X$9a@t$|6Fe_F$FG`_v%P0`obZk`#~A2Q8d09}U3)R~8SvReRhP0X`^A$> zr$2OP&%WX9CdE5X>pikP6F;gaoM;NXDvH6W;!*ae8MkIRnSnxt7{e=}=cIQ6oKV%J zOJ=uVjCtvf9Xpf9M^_Es7A0)94S%r>f3qD9WujZQ;eZ&!&N$+&(UuvPA{b+sgq}aT z&aQ>t0S7M=T(WCp%(ve&yCeI;)a-C?6yX#sLK~D8p^+^qma?V$BJ^7ikFpwi{_b3N zG57#n4xZNqjxpvw;0JFXP8APNjjrAsXQW1HbgQ?O>Xu4GC{-v#7>n>~@I2@2=0w5} z__V72ERn?_8fc>9u%L4Ea@F!plgzXw{ f?>z)8TnXd9{){w|%nPm)00000NkvXXu0mjf)oufu literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Key_B_wii.png b/genplus-gx/gx/images/Key_B_wii.png new file mode 100644 index 0000000000000000000000000000000000000000..99e7cfd634bc39152bcfc6b1bc594671e1c9e8cb GIT binary patch literal 1610 zcmV-Q2DSN#P)XjI!3{?^|6Op=-WR4ch&61c7QLQO-&_Ti?YSc`%n{vimVZ7k@6 z3Q~OV&4-B4HxVCv83N+m`XK0&K1+oTDk2(UTJ&~I?rl;>V+RdOHVA@Mc{j$OR4U1-si|tIR5}+$(bx3k$&=sTyLa#F9XodX zbYNgW0-#l%9?Xm=igN`TEWaj zv;rw|&UFCz@A&xmXP)O}eBYnFd-v}2ty{N#wSWJ9o|u@Z4Gj%-Hf0XyoB+T=N*RAo z4TMr^>DaMjG&(xke(KbzU);QTbLZID*mnTj_3PJ7E2AVMEr`f6^QQ{UScY{X>fphH zUjV52zOP!?5Hkw^R(PIQch1o#0uTTLAOa94-&dC|U3vEAEhUj*=orN=g|K zQEM6jP)a##ZO_r8NB`k@o@b146B83_o<4p0%X8<>$wP+@b+)ogd`8OiyqKBY$1;#o zYG(dCm&>g|<8~5&OeT|AJaXiSz)JYQ%;Xv=#6l?*SF2SM$8pOnwALvp<+u5Ke(B-E zhq!h@!1qw{8T` z4FJQ#!+oQpqu->{>DiMfPyX!i;lnY2)H@q%t#!`X_ZcKi`e+@Jz#q_22=V2C0|$D8 zAczZvLfizAOW=$}TU%S`oHNFlj|JdlrJD3J`F#F60I5tS^FjR@2{;2FRGCbs_Nf3w zM9hpJ2>wMx-ONnIVlh5*=FIfm+}v-5hlkCE4I6rvmX_YzXsw;K)&QufbUGa{vyGyt z6^q#SeQmAn%VaXM07_`Es0YArw`|$MH*Va>5YY!r(pnQUTL6LT?CcDP$i{KJqQC&? z#EBEGSS+?1V+H^~2!ZwM*URnOx7*#jcc+PH#Z69pH3D>Xbp-%8ilP+(h=|UgKfkV3 z;1#Jh+6@4pUaw0ux^GRaUAxxTTH7E9RP#pX+`E^qc{QIHaU8=K17i%rFjPqZU!_v1 zs9Y{b^?F^zaf5AAN(dp)qJ6iNFbq+v)ljKaP%f8IsZFKyyt%k*7(GrpL zJP*bg%+1Y3v$M0Q`T6;vR;yK$v-2mty}fPebXvEywWYMy2!a5` zV$lK!0cf>z=T5zC+qQZ-oz~7ddF9HL*#{3EENZPot@Z1{!NIRmsZ?D`X@n34jR#6P z=e%;cJUulvH7SJHP^nbx;NajFd-v}BOiF10)B$M4%s77hc)h*79l2a?Mk!UeeEIT# zwYE110%MG6`vf{{t^IizhT_eeH~-0Ivom+@+z}le9X$Z*%nStpL}XsSel1_UdiCw; z)2DyEu&}Vk_k9>+R&>fHApq^xT1Y83j*N_ap3P?e-QVBegQT@60H{gKn6PJ6({=I= z2mmht{F#}*c|UFtQ5S$e0$79pk0?Jx2#v102;gtbTm^vt0XXYJzZ>sX!Ti_@% literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Key_DPAD.png b/genplus-gx/gx/images/Key_DPAD.png new file mode 100644 index 0000000000000000000000000000000000000000..1316cfd661e074ecd6735065d54a111113bb82c8 GIT binary patch literal 1189 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 DTkIjJ literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Key_Plus_wii.png b/genplus-gx/gx/images/Key_Plus_wii.png new file mode 100644 index 0000000000000000000000000000000000000000..47568bace1a816189e6db175ce9fa536ed9f7dd7 GIT binary patch literal 1346 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 Dwr1rX literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Load_gg.png b/genplus-gx/gx/images/Load_gg.png new file mode 100644 index 0000000000000000000000000000000000000000..a5d9a1750f9440dd548b3bbfe962594c3f634334 GIT binary patch literal 6452 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Load_md.png b/genplus-gx/gx/images/Load_md.png new file mode 100644 index 0000000000000000000000000000000000000000..86dcf89113ae2c76d14dc65188b2fe35afa70b4e GIT binary patch literal 6767 zcmcIpg^7H=eg&(cjuhfdByuai+iG{K}F6&4g!Iwv@}(p0j(i$nv;?MR{}D% z5@?8hRJ069fg^;}4g=hid1{*afI#Gg|D9l!O7V1{6Yi^K;%ngH;2U7=Z4c75w)OUK zv$u1$hO0Y!+Xr}fyZFF$O}?b?^8n8>{_ojG-uBkM&K~Y?LuWU8kchC5C{jp71j3nJ z3<5ECX{jn3zRcRm4)h$K^y^jZ!2da%A0;Ac_>``eGM$*1ogV4JmJx)#b9)A96&sXF zhUL*K@z0dm_&dboW*&TRSKOc^PM1#VctN&`LlflF&!yPg^un; zPR`+b)D7~4@MVt+6D<+TaIa}@C3x6>SpMXMZTO&e<9w@TjV24BM0y`o4CeSn zeAtGMq+vrU5v~~j1uKcbUE2jB?&4z6(>Ot&VM{m_C5Q?)9P#$~vuRG2JgyLGK{cgJ znn8#IhykYxhx&p_U_+EdCq#QhC!l07YXp0N8*WcF4@!EX7NLbh5aY0?AoU2#1;Jk! zPcG7RYacw{!hK<4Uqsdg#7ctD-4R= zq@E(t1-7d%SeOez!tBhT2SV|l|3Yxel#`hCC}Jmi{7b_HAC!bJ!+ohqqYylVch6KAP%v~BWVAATi8o3`Tgb9L1Y0i`I-*hiWrjzkpui5d*~x9f4z z(ZPBkX5#45vv&|LVq7U-Jq#>hzv%_bdpA&5oK-2khT!L+IK+C(`Gm07(w}l33}R%C z|G=R_k?XZARw6brC0toX#5}Nl`6SQ0SWvzVDnY0&X4UqjYgHHqV+#>B_m(zPrs7h{ z(I6o;=rujq#^4%QMc*&O6Dhb7E0jVyDk3UipaI&s@hI_g_UMATV%?|2%PJwe0^Lo6 z0$sh|@ttk*_~`S8;5$z!fmy5bAC@4@hp~ZfAoVQNG5}H8}dQ zi#nty4a6dm7{{%&auHTONk{rp7t@v1$#kK0I$QEy%6+Dwr;G7N2!S5XU}08xa8wle z`l#}~htCGF-J9`WMY?7+;C`6V@^V@Ltp!=$77QYKd$C>AU?i~n|M1()PgoMGGZ|A z2n!u)oU|PH{& zutkantG+Y9qWuRm*VnAhnajjE(=PLOa4kL~3vR3){=B>`XIbWF_ z@Vm6M7>=OzkNIlxj3d8(;W8v#?h6PAyxjiOTj%EHM%L@q5I)@|GcMe?#46-AX;?A0 zdsi6p>Xu=rAov=5$|Gu%h}q4ISOWCG5C+~XZzx^T0dC?WNq%uV1jx(9lYYFYg2917qF(eEt-66_ms-yV`#FZ-9CD!1b!! ztsfCq9Xpt6*wKr2NiiJ_Hdmh&f|ka6uCP>~1;1s3?F!%dHoUv|r!hC-CMi|kTqdyO zAj&Mo7~cXwfc^27HZ2-?Pl%wKtCLs&dg;J_JQ_)Ci-TA(p0`^3 z0s^LOFGXtF{%LP4ELa67D}#U7rFM2ImzS5{7ZO^#z~3m0kB_@f)qbpPX_59iTp!`8 zph+61PUQ6E_E%DCCrasQ9f$~&R(hU^x5qf0q?7wGeuPt*_R9RMx8Q(2!1Hg(1C(eg zFXw+^U|=8~dhWYAi0ztf@xcmP6X`2niSM-?=yh(6R}`$QthmlJ#90aVU7j7Z02_l* zFDM*!W?^NG`))IB$iKqCz>uO>!py>g$kr2c{>|gwe&*o6JNpAdBZvEXGS3=(x!*fC zKR=(a)p`cWR5P@YLPYTSJV>a~(4cafp+7GMZ_9N5F#1|fZsy3x6*4k0V$5_O^ya6- zTxVyek~j;MPKJ1#ohWu=Z*N$=U<5Z8fVc1+c+iBDkdWY^BOA(*AJ`ZzadvWor)kF+ zSG{0(QELSbKH0TDKimkpT;g1t`eX~xY7~#xm&`26%R@sc7zq`qt9}7NL7r?z);n>k z>$|(F0OOX{M+z=adlgsPFLsxHeS8EJY9o9@Z?$fEp=*loA&ymUp?Kl{Z2;3I-RBi} z<2gmwZIk=xa-h@?)egyCS}Gdd@N{-|w)$PDl~Pw%r>Uz;<+CF??&k6U!Yb)X z>M`3qA{}&i|IcSP2%L@D;K>u*;l?Ny>4o^yylR?Lx(JZ9=kfX6+KG$-8&EROuMB!I8LG8vb`YQir3~ZN}}IX2!PxE{rh+N zplOyaQ_6$GphVBUCxKbD;OY7KIWqKI+@M$|Zr=ZoTb67ceC|?MUcgI4W^4krKZxEPuhQf&EPuUhK=P6OCJt9uK%RL5!fvod|Vk>jzC#? zZm1>H5(P=vq(7us_f$xWLT(#rBDb=@B33x|Z|0p&PQ|W!f(PD1x;|jiymtgJ@fVT6%IajHLf<-LZmDJ94+|rB~ull3@Cv= zMe}fcaa+Owc9wW^Zn8egmfcdqcc>>u(^( zXmMO&`}t;txP%1Q^Zd}+xYDGv)o<&s`F2lBUqdr1ioGN1iD)0Rb;-H>Q(5Os4@%OZCOKxT_WG|>O1VtwhU%Tzm13h4*`vw|F((4 z=2+R`;o%#ddw}+Ia^$d9!kS37;?`D~ZKNKdFNHe_@D@Wu!(X$rgA$YGT}IC>)a>o= zqRxMRSl`;>#_H6CoOvTsNFfkNw~Yu}ul2zD2d>j~F{+48K-__cBN}}C{5F6M6GthN zQ&21|m-Ea1D?C=Q=)yatKa?=|4{8azro?lOdcFrVKo)6E%JT00d&aq-t*W;D9#(Nl z$vXErnR`0vN&qo-c6PRB8sn?Xny8CMH|C>m(JUz6MZo12I`l-{GdQX;lJlqb`UxrrVB z`UO4;h3&@!zh4`C;=cMbQ^U(kq|EU3$B$epA7MaVIM%keD|qhCN(27$eg13kbX%a< zQr+;6o>)%L}h1ZPtVM}I62*4QY{z>tJvcU z!M`ZUQ(Hw^3-=-X?a1nQe3rFAZW4HBRS!lps$YB#Fw`&-Jvlxu@$2_*x)uO+>6Zk! zS(CdxVBm*GM$?j1CG5g@Ku_iPTz=-j|3)RPuDFlow^UBKNn($$n0JpUt zKb~&(vh_UKo%RvtV6;4(s2<)?8I%A>~|5IY`W|EChc%pdSU{KY5 z?yL+UKp)@ic!XzqgecXMm2zgYjWVak@L!9sf(?BD}Rh#xD=Xq&sQyzB19Gjvd2-L`f2 zC;h))Xrh)k-{eWJ5doQxd`Ym{D@az@1j>TXgw2W?2P-S|?ykGGwzf%~9U1Ut!v+jg zY56t7BkUk^7VyYQ^OjU5R7lF}*W_%yA8Ts~k&CA7A<}^7bpqRQ_e*PQ5YvMf^qg#L zzQehSc>K&v#?JaWL2j5;)J;nRLF@Km)89y!NhRd8$57hf(=VkTsyvZ3GRBTEAN&a6 z267FwCJy}iToI9A?<1$AKG~$VRK!H{?V%UXJiZ<=Rv1_Dn*+lEZdF)V7_G^pB8u(y zvj_?bDy^y6!`D0NyY9?14vjxY=>h^RDk>r-0@KA21G57X#{f{2;KPUhe`aRrc=fUf zAYQsSN>evNrT={s7MU@;%+{xpO#i~i;U%=Z*KeS9EKh-NCg+`YIwgJhxgF`^?{sI3 zdg`_nCY6blm`G~=rR^e6KgYRWr(opA8<$GTBk7|r*Nv||WR=*(uM8gJ zUw3>id^{jxm!!C)4R-6v?d9EH`}e5$H>|~YUafhIkB^Vc$k^B$5GEjPFN+UAo%d4; zujA(@@g-ny6~JM~hmCi1baV;ee~}9i%F2^|^-)n#SXBfq8w(2yd5p>#q}VRrrQPet zO*ZES`GOEhD@m3u=Jl3D^B7Tp30#&W3X1FfdGr)AgIQ16z~mefj!M~MXt?0A=nr}& zVz;Q-)=ir||CdMcSRh^R-n|PHczQW8Bxh5{|)NOi_V`*QdOfM$(@pqRDwzyYZ5+iowtAaG3 zPDG^|#pe9vP)(%%b0&5JFFM5+oSOIES|Zu*u_XSRajAKVLg|Nw%9rTpa;$G`Z0Hv~ z^Dneyb*MSBidamoSgTtmD)0SIP@<^}*HBLtx5M!$VFzUMy@Y5W1=_1+jGZgqJMJ$J zJAWg6WoOr7XNZpUbei&YBBf1x=q){FnMO=Fzqpv=%?+WO^fLgQZLNOVRXFo!vD`2P zGU;u{CAejGAOuC6c4-9^25?|!Nd81eZzSOAt*)ahmPT*iLFzqElq-NVT1tVidlhQ!$0i3cso zU1{MyS2N*3$~jm&es;Mshd!!eD>+#enzg=~7>d@_P)_K1dLW&o+NDD3Bn5ZZ{bW>9 z%u9VMFSV+`pxC3l#1D34eis3bjfJ=rvIWtN6l9;qy&zM~b!tzMIVI0vAAb%?tKVs0 zmUq0xXLCAqYTBJIiEuZk`Nn0`S6INp?3$fi5%2g|r+sRs)g(EMZq*>;q-`h%)E-5- zt`?D+a!=-xl1#D*j8aeK*zD8wBTL!pcX}k0#+J8c7$PAzl?0kXdql*;t^&kFKRgt( zw|k>Jb{aY1H{Iw{@!&YrAIIySZBR?0bCauN9DNi-ok;&{?o|7Nq+2m+_9y^|_%x~} zSGFE~VpbKlb?!b)6Bq6s{Ctm^$F7)!$3Eu=6RK~ec_3xSbZXz?friiXG(LJen$zbY z!m$EA-Dv)F>eSOBZYhi+m62`Aa7u=5e%LG-G0s6XOTHUDNaU_!erE;Nh?7Jg8=iRE zvEC;5HR&n(>FPLYeP*fkYiW&vQg)2rD`Dq`ilaTXpmc0VTmGleYO#AOzikYj3gut0 zz<65+-Wf%ldI!LJcx*ODkjfq7*hL5JGpp73+VjDnp(L5+tv`Y60=bf4|L^A{VvIX_q?m?IDWtLyMkl;L9$=XSH^cY zPp>LnP+ezfFT%oj_-)T6qia~^p`R^C3Z8<=Z5G}3`IIPMQ8}^ZdsIX;_Gw!Wnh(H1 zGn+E%?w)uuwjp;kV(Pl!9L<3BK;&=DkrfSvtIS5+BL+VgV;YWO~G@*YAuX^K5mN&`BcyZyn2m z7Omnpv!Xn2tLc6iU(*ttml^0X6vH`FY0i;#vL^UqkfBIjZT&Y8rhMaRz_iUQ%1$Vgj4GksHWVj{SbLJ zxYKIqZg?%3mdlvj>1`Y*6H=5A_Y32T*j_62v}`|nbepj^q`$9KYpf4MFsQ-bhf ze)>>_R-wxEUhcZZi=c9`|_=-9S6dZyCAmBpv12gOt+A4nk2*qw>&-_BlrC zo3ZirdpT;j*;j3`XQp=Hs}2kJHHT{W!dI$Hk`rKu& z{&4Dg&AKY^zBvh$qrO}b&K{-u)YvDmm^Q?nb%MNBKqE%0Q5nG#2v$F)za8Gy#5YEF z;6kFcWpv@T9(PlnD8KpMMC4|(f4f{ut$M_%V$#BT<`@$UOWGi6$K1RopIa+SJZ;-p zP`3NfcYC>A*Zk(b$6e7oi5REwJ2y3)YY4V8jP$kWHJno8to26g@;Q7iqJv%3HYpQU zy{A6*>Z-a#n2>Pxb!;JT4J91vMs&?|Q1&6f^=ZhL0976jBd!bRYg-N zU{Atr$Uph4?YN2FBy5w9Eaf@RGOM;-)1FdXhH9MOs6tNByGjYV4Eam#v6wY6T<+V8 zZ%nY=uBn!53^FQZqafdp^6KXd5p{h zVjGqmrB4w5!6UY>orLW}=6r*S_#UC+i*GPX*rcdC-;AUAEHw(Zc&<5fZ9wN-`TYuR zVN%%R^_!peu%Te;@X;L_T2?e)4Rmq+*=2Z@kqp%m^PsKX&8>bBuB*`=H9YW#4@gT* LPqkXbD)RpTZ%F|& literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Load_ms.png b/genplus-gx/gx/images/Load_ms.png new file mode 100644 index 0000000000000000000000000000000000000000..ecf17d0cc2806747d79c8f116d664187ae27de99 GIT binary patch literal 6537 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 al8cy?0L6+mDg%FofV9>1kkzWTvHt_N7i;$b literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Load_recent.png b/genplus-gx/gx/images/Load_recent.png new file mode 100644 index 0000000000000000000000000000000000000000..f97e5775b015d42378902aaa9d6f8cb3a337feb8 GIT binary patch literal 5676 zcmbW5hd`90Gw*!5=<&0^T2j=QA=A@Y?(3 zpc}jqyQ{(xWZ>aXX7e6=zy9jsQ+Ei2eD}X6foiE_D)E<~;9~3HW#xv1Xj@sk zxi}$hURpslUb-Q@T-+Soq1q;m@d7;HT&DldRdYjHdAxLSh9X`%AtB;oq7wH+#l`nt ztNTG9j6v`RDhTh)txP{elHqKp(r?Unj4MQeoq+41vbtWPH8(Q9ur@i}+I0P6#EDVg zXM;L7)}eGE2TVs=0Y1Z_pxnG{n6GT_fs~6*jL%b9dd2i&z75feKfzkZd zZHOwA@M+oT9*%H6r6$4+Jxs(F>`E?zS-om)?pdLQ^O}m+Lv|F~Qh?{Pp^#Fe4PQ%q7P{|u1@nn-|440b z76a+zsG*Xe?6>hcIitucyYsAa+#w87YUIGDV6nt7P*<>az22{5Q)){ArZ@J5)QI3y z9;_oW&zr_6ni5gm06CbEVlYDAi@{yG7X`=X!J6-Uc%gQtrqAGxnrb2m73yJ^^(gK+ z=H=yuNJ>db-IJ2?4U)(m-13wQT0A{H4e#ja$O%fq?J92!#Ka{hA92%mWy5qB+86uG zpEdiZvD~#K{`w5&d(bPr#Ob@nHEdtIvk-q<^P!ejqM-oe%F4>}@^Tjvi5wmtCNr;K zPI?r^17GuyU0hm%KYsj?go@Qh`X*%(&c~8}_x}8*^KC=oQNKDnB$Cljo+CXyos5El zD7UIAesS>yHMz31FEv>tXfBV%!G-BA(NQ8(-2?95C!VtuN zj_cOf?ep^T{1+hzV`KNzzb_>uB*roBb`aYtUVeT9eSH;E({x9vj0uc8KWD%{E)X)Z zw?R-cZ+Q+LxN5>@2MLO|^YkT!h2ie2eN`@ViXG8xc4Kd66ck2GIH4d zo=y?{)8qk^LQ;Ba_qukFW2ykG-S?t87Rs{8xgwt>b#-}T z8yN3BZilh*mB9k7@Dy`jyneI>{evl`sz0_#_Y}~jr9W&WR4mWF zY*pL#CRA5f`z(Yp!-Rx*xVhgJ7V@>WwWZy)qc$kg;S~{yiHoEC>#OhLwJ;v6LPA~Nrs)eoz105Jgn~LOM>~WFHgFQi;E2jB>(j9 zuk^TsA;5AdZ;C;J2#83;kli2mYRaO&sl~%SP>@qlJgswNxqtsYI36@QY7|bx+1H&U z=ySf;34ipc6(yNBfRbe-RW38iAKQp{{~pTA8zyeu0qv1EIXP*Vaef;T^7H46=#p#K#=D=hd4T8Zc)@uZ8e?m z_pr-*$8~i*%+%pOp7G+`X*!^`?ub%BkIcqZU@$E2+En!P^ol%3?C;Uh(NS_LvM2rw zg?*68(y1{O&V#+EGC_dL-%;k!>rbO%bQ*Gf#{9aXNIOmq_fnsMroKhS_b)7jl!i}U zemX@4C)~qTYpQS=LZb*36r`x0h#JD%EO*5>?RBv6@bS&YsU#!6R##6n`P?-vOMY5y zEAG1ZLxiHzL`eQ{*Z}1D<-blP5RW)yn%CT$6sxxIFzQ>ff1T!KvZ6EvCXIe9RRoB9 z(}~OMBNq}BR4YM%R9o<~tuz#@=_~%cu4BlO-XP|OQ&>nXaq6i19m2yt4zkL?Pyki z=X8P^U}yhzesTcU)!mUu>{-bxFQ+auiZntO0I3NN4;LA#r|014162afC@L+D+TDHC zeDa5lnp2T-mksCthQm;^9%E=~X2t@hsu|0HoNjR4!WK2M&7RJHS_JvLyiw7jQG&=r z2(ZX`3c3IJg?Xu=Lfem$MAe$UefyS-ntI!)p}krVIYh-k!o_HBSXh_go9*x6C|`1nAoA=;fa1lK+Gm*G0u@^CFJ zt+RaR<7}7alftUn+N6BV*hSCA>*VCz_wQr!*RUF{uHxF-+ReYYxVRo?%Fu;;59(a{ zR9kDP7;xUOx#z7xRCVisq(+aDf}(BVRqhZTxZMmkfTS`hIl0_GAc=v2Ay*GZcKtfn zy?aUh{oCp5>6@F5j#6wXBG0+S#p8=|0@DBe^CniA2T`yBI=Q^EGSKYnCBuF}Nunm8 zH|~5J8ob?nwjIMsbpLFEgNdnbesiK4mo|7gN)bE-Zz zFOS>iDW9k)4G0X_LptK%wKY^iVj`#%l@bIwFs0#YO{Ge$VGXljqMh6fDo zZH$bJACr;>1_$2)!;qKHOifL7W}a=1cd~HXoUDz+`W?Id`Nh&?E-ITv-8d7Y`Uxs4 zJDH+eW<<}%7Wt?^H5vKo)2HC>?nf_PyeNNaHcb}{;eqFU{d%Kl2(G6`OA@k>o}Xx@ zUhrgKay{^&2aBu+ELQ1KhDPyU?woj;Lab?-M!}O$MrdR% z#yWkLw)njneQ|c3Q*UD)><^fFg+xX#N|F`CIXXHT>@_V53;s7Xgd_Id{7_M1db+Qc6i9K`#u-p0K?7^l2<_iJ7gW-x9ctc@#DvN zH;f*P;p=xxoTC&4?mPzXs|ID0HfLje{>FA=(;l_bom6U4wOI4hhSf?Ut+=G*6F`90 z*4B+g&qrX>V--(fOp(`8delu#P3u$0l9H0n|1HG=OKvi+aI7*RqoTrcF%@?bM&y|| z)|y75%(Ty*t(|&^wwy~?Sy?q5O*(AOwFG|u3{O-grDliy=w9(nZ;x$M5F6dLV0m?U zF+4VAEs++-18>-AKI18P;Qav5IQ|@eLfq-$1|Y>B_O&8lEmHG0DzinX2l=$qfAoJ+OS|vR2e>Gy1vATG7=SHBgGiJxFafHXVKHl^Lxi~*SlH#B5Scw6rwf*gy(C ze-6FpF#789{6zW7*d0J6O;?v^{(vp~ncPcO~0+Chh6PAI30W>y!cgekpVM=T3gG_{r( z6up1{9=Eh-Dao29<-|&(bS@SV5n&>foWbgVLd^pW&XjR|tKfG8SSHB4LNkE}A;3t% zEMoIBffps2K7-SCA@k+wPvF)1&-y{Mlz-1WW@r};O32L2OjSBxpaK46Ep}6{1Oehm zLU|LnHjvLE{(^XKZx8VBoNEM>3>v5rW#whtYP35wYzzAA|1iNUv#g2OU(nm~C zFcQ!}Vn#+}&x&dZ;#75;2fm-RTBDhIhk<-fE?Ps)(NTz=@3G~dUul59nEIL6JbI?7 zg9%-$b-d1v@4y5Fwa(AxuKHRo4@EzG_)v^S=NA;T^XqleHs$6*L4}KpivuRiB<1ji zphryA%!oUux9e6t$vn``MnAMY&&R6h8h$Ul`kblYXXL)Os4gHNfU>vWKTMB#cU)Cf z1s33Q`}S>7!U1<;dkws&2+VDNUsY)UNG6@3qPL882B|D6@sXs=9<${>eOq# z84lWkJ$GY~;pf>K*VyWRZ7~4(_WG0~T;JY)nYh+l))C0_hVbN*E>!97_2qYp!RP(_ zah#{b`)WDL0c-SKH2?oW0t1!{hJv)>OSxwddAk7{6}zvmzsOU?#wSvsi_r@stYe z(d663#l7bEyZKxaZi!y@syxvENE-`JQr0B}9?)?}^2uNK4HgoK1M zFn!IAA3v6-!S#@&G#u=H0DKCl-z}YiYJ20cJ&joggcwS9TjL`Yn^Y-XKgqRg_beD! zBg)L`o4r8CRv8r)l@q0r&%ne~NYK^S7t`C*qg7=hlnqbhV=Ni5pFl}U5k14W@#3d3 z?tG0i&Lj48NWL7%Q-7GS92FV4RNlC4dIV7Ps=#`- zH$z(V3}2L^y3=xXdCR5c;>h6E9RBe1J;0b7^z=#=Sl`2Y1iFAF!vW=NdNv}=%;dfF0y&LtE8QKTp`ks%rXG^jME8e?Kcpr8x#GqJe{v3>Y1nojzLo$0%vjug3J#ZV5Q3~m%v7*`IFV0z=qON$A<_6V&HHQ68i2Pnvwk4 zT;SE4Nq~^`ipSILR~G}CoZ2M+_BuINE-%h{s_lL^Gtkpp2Y?)r)=m|(0$%qO05vS? z&Dqg&N@{AO=NEV!2VJEyaAsj(6o3dtGUU9r>qkaLXmnG>7DRIbFHbBWVE=3YAVSFu z5CS9YSaT&#+`_Ae_O+&W$W#sOKsQ&rx*l6kb%WR{Sf}U=U`YURE(Y_|Q#NZB5Ql;< z_HwGQun?cXqiqOdsO5<5SWehKGv-{w=&aV2WHp`S_eH6OmFsPC`!5v9oWUWl>^;3pMAziLQ~T;uN~J zJkik_w|jeg8;vW>FE%D8Czry)!mP*2%%n+`6L>1dHri2=r;Cg!q88ZpOknI)4`;K4LBjFTbwczLsGrndG$Ws?$tgc%+g9qkUh*sz%6 zka=afRji+HW7*akMsWZ{x{gmm;_G@30IT*N5%e3Yy&3$XW_6n`5ZSEl1fd=`PtPN@ z>({Rz-nnz99OJ$kK-51xj97HT*d+dBAn;C1OgsiR!@5B`^eClgg}x22vu7i+ero2n zYc8pXlucLM`R?xS$F;RJz94X`rGlHAyKvn@mQh(%we@FsI7uRuOt`G9%oJXHVzn=L3N2^Fl&M zsJ<1C*oy+s6bJ&ve&J$hIKq)XAY!Dnh7wxnp*KY-3P|rDQWOvp1u4=6 z4TLHnz1Khx-~7M9yEAw1mNT=n_nvcSb`u|(=rho9(g6U#U}yj}C3!89InYp%`nqra z>m)~kxNB%mLuz3(@C4GF*4Mxq0RVLS|1;3tTKOE(BE(0e`+5s7 z9G{%nB8Fyc3a@bMu8UjPIV@yf8XEzaz40P6(P@FFXg#R|LHdykvVDQ%v<~!y2UyV8 zR86-U(0)|$^d3b>7s7FAYAjNr_@y)U?gff_@IeaJU#q z6dH2c^bL>~px*_l-jCnag{lLb8RHh!5PHd6`)oJ!SHA(-Xek-}9_7_MGAC-f1d6at zy|LR&6pde%_)_N4>j!mMP|eGGy71=J;eT?Ouun8ihOtrD%b-ZV#p-FXgzzbEyqV15 z>U?MU1Iu5%-T|vw;C_*LN7W-1{%3{yJ#}mceT+{1dCp#x*kVU{O|kmm*H2FeS7AR7 zWP32_Im@&Z>aR-qGdY!4yCi&>Ge6j01M0B$5dODX54&zueq=Y-v5;RQpBNwW{9akN z)}_))L(g|nKrIyI=zxFgLm9|k&NYN83I0VkzAhda+_TyY!Z^h|b08ms=V0dK>s71h zx7;=iro04)9%~<~x$ov{fBhxflRld3!40RllfLd(;x6vB+pUg>?$@k*`pCjeXZqUZ z3z32;8NjH#q&i*!O7)!&Y(ED^k7ND)c|qQE;|uOb7)H>Ukl@&c*70L^UXTTY%?NkU zeInmrl%?Ur4nMb&Axm-xFiS(JN_h(YwW=3;M{L5eyxa!_I+s6nQXL%U<3*W$`!|$8 z&%<-*#kPQmJ%DoJ4FM8owuW4(m6B;5ez%EplmBU=?8pvA7cCPtyY_@RIXS;hPfz>$ z`86&nrxDAf!>dj+^?468Mwj=0cmHm5?z>rDUcT*XH6z8>3dc2Ei)3PMoOjG&U}@~4 zB_I&Sw2v}NH+m$BW2(jQ<#HxvrhXcuh_5oWgs#2gev?rna z*46u298PHgkIzF9e#eL70)p4_gOK}QsPlyjkj1AR3x9XtZnY}{QNfR?5~&rTegHb^ zpB@=gfYLMI2)YE58*b*>`IJ4Rf$|(FW!ZLg3n5!|D@vI2VK@TObX!^3z}A+>$jAsT$DyjK3NBcaRZ`L~ zGcBsBN=!_o&CAPk^YnzD?apZ%8yjZ~yLLJ?8mQ)%KNNZYbd>jkNNih9Q=293b~LQE z;Ow3l2)%p;&1UAZNH^GN7iH9<`J8O!IinjFd7UB(u|8Im*AVtcylX93LPBDZsL8;< zFdKe0m$pYlg@&pLo4j>c8_A#i^$Sb^YO|424?cveyc`g0@93B_7yC9j$toZqFf=kE zr=l{@c{V?I^_MtTUM{3mI65&sJuvW6cw=|ByrLq0eEd-X>cV}mo9WIm8jaR$ltz1# z?UKzqBtExnYM@L@{ zz^5<~cgjo?Av9K2R*PTbuEqWS{kseg(&F z%oL@jqIf*spkjhFm=8NL-rU?oULN#$ge_RUDVbQN16wG5Fi9e3hWMRjfwTg;$b9z~ zznBZXENW;-FVRo`K#J>&0YS?KI|h5?@3_kuAB?R;_TYUJlf&=g4ey(qp;Fo1e%uu` zHG{V}IA|v}{FQIt)^T&^)2 ze$-67rLC>6!-=PDUS3|D^c&nIyafKiig_+FKoFvu{z*~oAuXcKrqNvNk)>r{+%>kG zoE!&F&y@Olse<5Djs_d4inZ0%|B)gjEJ)9gXaK zTquxWrCWKfqN=9m?(XhLJl(PR=-BH@i=9dig94Js^ z+kLt-qY{4MkKCLToe$mXe9n&kJvR36{7<$$qvplBz}n`|8tw4#PAZ*E%B*u{Sv&)j zWeE+c1jrL)-4!A!B0HL!&5@_mPmQvrY^yb%uOyHp27UTe_~~fD|0p4#pSIu2|U#cZ3*o>~r^3*|a?`TW|N~bZ~Nte%?0pEtyTcq3hz=!H+T{N?btx!NI`~#Hfbl zf%>TE&17T&n`+v1GM8o50Dp04h)wboH>GyP=VYud^hUffrk91Qg@K@fSm1xrKEeGv z??oBTC@Jj?V#O1O~;V2u4#yPpUv=tQ4N z({F6Wi}y+fsrYMnIE7r9lQokBVL};LiFgA&t`~{kx=>AzdM~{s@i}Z&iwuSnz{v5q z|1?oe>z;!-!IrTKE>JFXek`*jAVAzzxe^8QjGq&)C;77UNcw9G~)%ExsPvw=E>-IbaU z-IW6QPDS0U-2$Nxc!=skl6gAJSS{6+OH1!mP_Fw4w7UBl6KjTRvC|;G+=bduV1UAE z1GQGdyE*F1E|r_i!=H~iPre`$>R0KPW6;5p4y7#D<|v!rjQ9wU9c3rb`3scQqYz!! z{l1ly<+Q$;Fey8GsD#NcbFj#8Rxzwp>SpuEX!iF{SbYN0n)=z8A2I&|U!WqOja zInLPBKy}Y>D=Gk;s|o#2zGn`d&?sb(j3ur{Tzf$_vCRC3eT~H(ubb6~mjUu<^0jO0 zU@Mj^2F&0P6SeY_XKL;V0-z_ zrAcT4l`CRfC?uBsYN#t;^09)KUa6-UKo9Z}xKTpKKaVknQ_Jv-Q*X%s99f&W@A32` zA|YkT8@}Rmmp+$D+lYoa&r_1cqH;U%*c$f3LyKzjQ0%gfPK(7b(SyfC7g->3wA7nZ zd%D%5nBV()=yo9Z{KUPxw3^oDiSN&FF5iG|7eUu4hPPI67=>4T`pm9d%sfpV5#QmT z?cDT(T9MCYfpH4`TyfZ%C%NlFdO*t5L1h1RxV0VXN#-vyY+r)dI?Z(P)6v1@HTgHC zIQR2GI{^o2R6+xH$j}3blS{{~4l~7=o~xPN2YZc(P{&%HT1A^Jq>aY*5nXw53i3ACV49DB2FB

g<)^4(@vGphtd1u@nzvNZZb8`+}4`ZlPh}Vp|Z{os0; zzVVaZ+QxJV#Aq|fYD26gy;`E~kKwJpG1uRSr0ii_VZP=;EqRb8dO^Fzu_^cSzuw&1 z@;-5p$4n}+)cvR>_S2U%u^ovH-#Ymu_H6n=UG?3hr4Y|MMoK%MTb&y&-sdL!_=P&o z6nu*EXD-RtrFXJ`F#*{b!P-#<71h=UNO|_No2PziQt#F5hFzx=dliv^u^j2l*ZL_2 zO=_e|P5@s@BsEJNtfu6&Qj{F;9@?bF6O`Brn?g`pX}0^(CU(F&m^NKh+tPTfm;k;H zVN}IP2x^{p4!LFt_DbcgX~Pmw3K`p!+^4q{;&9PZQPrR8YhEM)?~;p`N-9}Dk{|p# zpwMgKzN_%yU0^Y6h?&}Y&w?3mUC?dyYdvILr{|{I>k8QW67#y32f@*4Sv(JVavNhR z30;ybt!s~9T7vIVZ}5LTA(Kg6+1Va?AJ}iF<+4@7qfGfrHq?Hg5uZS<7D)7yUWVa5 z_4m|8iNyWtr~5J%VxQxi@lGVBhXPiRrjIy)2y5oi*58;WgrELx_qlWJ^%|=w)R0r* z$5DA9TPA!&q1g_2ond|+ecr&quG(IIO zqVkJAcCE)9Zyn<(HbOvFg4G<}`lhR=Pj2}YdZ#~Dht>96Z7CcC#s7d_lWmFq9GSH% z&vqc*qie57|A4vdu-=F(_^BIb)rJ3cNw1G5lLbW^ZO?AbE22*CnT1BRmJbIoJS;r# zj5b&bF0N+j2fRWOhn~qNNtAWG^w75$NaabUmS!AW;HZ`*w%;}WcFAvg>yn*ijj!j% zR;a<7@>Ib0hH~m8wLi-%Jm|j;L6;5#Vp%d(?6^BLtZ(>K^YHb+4Z)(eSoZe;soOC3 zl7?XhNK3TD*GR7w^({<$k-A*FCK(>smy`Q?E6>;?_1*!nWmc3*CX-X_d#e4%>UgP>XT?uGD?5+UKTLNMMSad3^T?-Ywlc)W|S0;5sb@D zOwd;g;|xG+JNXl1C17fk(Nkd#aHvsx|I?p5vThgqc;f%Fi8%m}`vXdG7)tf;-~SU~ zLsBAdA{nhiT7R_AE=orgKI!X<3FB#{|4ezAt1?e>d3)^Jcc0+DGz7)Nf_+?Km+Z~G z1^Rtq1C6D^jJ*_#t&(K(@~$HHg9wVN1h+c7mH-r^X*V%+@#7~H-Ry6Cnfph8m_hd= zHsF#A-AGt6O8D+U%)C4FG1JoV_|>^`StN$?YIwiIh_GxFq`vY-K#~rtvAWuk0X{xi z*C<8fTzH-g;%0euezDp(p2G^}R?igc!*?_&u2>1wrQ8b)>P+g!0e}?0eeDFBIL`qg~ zS3>32fg7ry|C9nLKtx#n*743Z{kYMOu7E2;kAFd#<0vMA$JQrQuE~sSwVBXT!s1rs3n6bB<3&eRSz7TmLbe z%KeK|Vf=}?R;~9wvKHJ%a|tT$7U%f#ai|4y%RDg@wBrm~pBS;byLlo0h|Id+P!fK8 zjA;Ei`&!QNNl5s)HI7mZ-6-2rzpZO7F<&6{g21xRd1#2)YWw02-PF{ZJWsoEK}h7f by!C_qzQV}z{hOpeNWf6n1X_RBA^QISl8{so literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Main_cheats.png b/genplus-gx/gx/images/Main_cheats.png new file mode 100644 index 0000000000000000000000000000000000000000..a9fdaf62df10150b25a11b438b82ea191ac402aa GIT binary patch literal 2122 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Main_file.png b/genplus-gx/gx/images/Main_file.png new file mode 100644 index 0000000000000000000000000000000000000000..0332f5ce929610e87e2caa07f255b20f22819398 GIT binary patch literal 8028 zcmb_hg`Muf(p>`5BCT{wBORkbQlt?O5s)7xNQiWfkdhWD0Rf58 z9q-|Pcz2EM+OF~J?A-VLsS~56@q~nso)Cf{5*1|y9q_CL{!H+3!QNZt0zQGb{lqgD8&7X@cWX%9+|u2}$=b@^9HC_IZtd;j?&yI~H)wpziG(1gFDeSM zx<2o>b9_CGCz>&>wm-RM(%5{{EFb1tJz?G(2@fY0A?Fvuf*HZnf5Jo3I#l}te|xK# z%g#P$A4!>?YWkf-g+HRE-m3ub%Cr=(vqZlu^GSB^lp8oqq8p`)(%0te$DJ$Tny9SUvF0O zy!c*oIVikvxgAC(WniqU>&Yb{aY;T5XOfzdoyEN^Cw{GRRXb#}_l-yuP*dzMq#ENkL$crWhC~`TW^40d;mNjj_$6o6+fM z1CCVH*51B8(Z^sdVsUMk^Z%ToA4Eh%&%Vv=@cD2JSWK1~)?#5{=@g89{^QF8mW9Aq zF4Q5%hNW3+>*@8p7x%6Juc@tVZ5tCA#l2+nwHOSW{f-(^Qc?yW6Yu<%2lgGXpu^E8 zcVAZOE0K3iW0aG-78e&+dwY9*8t0gvYLCjLS5^?T|j89eYSZu8Z5Vkk#^_T$Ho{Y=4^dz8MuzG#>yl;P95MU$n4k{D)_JRFf9 zWlF?rcUDbC;)kw_`yZEai;DUhk?%OA5ah1OYEvO8`ljXW?d%{$?GnNW<_R<2vJdv( z%fa^_cGH?lJfewhh4b>hJ@FDy_oSUX4Up*vDyL$9{7`%J=uyRl6@MWeG4A;+T@t}(ydE;@5E<0g<|fg_{s0eA>*fAH z$LZ;*KFuQ&pOPWpbY#w!51)CZ0s02Njz3`;k*bP!adFXTpEblH zcNdb^a@FhNC8mp%_4ck`84kWaD2u-*eC;(=@uHQe@FnF8{IShf(T-JjSuPqZx(!wS z%(BL!qMpgw+0vXg#|UJkIf5p(otM}y%WL;R_$O9kv*6(1B4wlw1va11S2IJJ?(Xg$ z>W6x+o0H{Fad&fS+OlI1_^u4XbgFkLCnJPi<|VpqzH;=4k8%x!TF(qX%t#8AONAGX z%+&bUk#eHJ9gq%HDm_;s0v~iB=+F+#$&`4`(C4Be*8dc>DPK1vQ8OG%FeN@tac3n& zSXLP%2TCnu!1nx_l{Gb=C@3gocU!1zZf+K|YCKj^;4Mrc-N@+grM7ed{kWfc`|5NBgU zyX`Kv6DKUU=np2Y`Sz~vFI`?Qe>1F*A}Mb>*^ zdeivSTm+pceX6SBn^|=ysL1PRnA>rHmat`!i~fH*l8^+6=w)bku945VUYwg8Kh97n z&H4@#6KUS?6olwE;|&j7AjXG$nqSh&nRsO4qej)$)j6X&VW45ju|aPYsb#_ob?oWs z=z1BLm|89<7iYD2TY9Uvcu|-DVl~pOoianUSqSbmK%{-}`os)}#uxBD>T`1&#|GjpasqSuYS&$+bs9q?&9&lrziwsd? zCGzbPv_hE%ofZ1o*(poSqg)xHwzjr#Bh8hgI^SY1`s47Pez^(??lr$jg6&J>`30UZ zl6=&IC6SPl_L$z!yJ%r2#}EGvmyhp>&dSbSj*5yx+aQ8k@AL8TAyoDWQR|>czMoUy zH7Rt@);+mqT5vcBb^8v|bB9BJhg zQHTr_iXgvtZ*y>P@O8M6mohYH<3X>eJr!P}gr?ox7%LtuDJhXgs_2LWy*a7W+g%#W z7A7+^G_-Se?uj6xmC+s_`O_WSD9p01ExtAD>-N_5MaeZSWWNbrMK~Yf>`vap45j31L z&VfWpdLa*!&6wnRh#JS?2MN_Uc`L`9{?lRxCaz5oZ}l3(={d+=7d?LeaGB@ZAs02;K zw(KnvR#jE`>~+)TkJ`EJ{ZRyy{^yDG`JGQX9Iu4##VN6Ha&nH0j6m=D!rR+rMRGKd zNTgYR3diZ`aw6F7q?{a*;xU5k!N|XVZ2(R(h`2&JB`M0v%4T3=Gr)BIE_qh`mz9l8 zxei`hz!E3aqfYMg~FqBqK%D> z5r^8_@7e3Q=OV-U?g2M9iC;4lxHmL3jBI!&DI?c0m?ut7++dAKDJj^XcF&46mfG>| zcll$Q@xIQ)_4lg^3JQKGEX1+-dRHi$M8CqMeRUwc%41DK8A-8zBK$g zk^;4T{(X+GP5Np>vrn(|vGe6LU=D1!Z0qdy&e_)2;YoJ}w(n#6=mE?Li+}(nw(RY7 zv1QxV4)Uw2?o3QfOjlXrSy)&krKLsQ6|h;%_1}^8@)G(xn2i^T82SC180?|x^?o`z zKDM&Dx}t*vC+beY)ckzHuU|%jLPCE4WbtMXf|hO1myf!=h`wpy5kZNrA46O5)YNtY z%&2@4nTYmKPl>QL{8U_A-*SDvIh1#`Wm^&=BSZf0bnW2mgBCk);JN3wIcLyI?P~|J z2=chQcfdS?3jO@4^Iq&Vp-u@EXDZ?C7H%GWG2j9kP%LNXet$7Lp}oDm^3$iCZ>S%( zRdfCN^~;QxPV42%gw80kf)5{{fpnf=EEybV`Sd^@mhsQ45nWe>vzAU6@evnNPqx}W zdU#z=^bUb9!axdm-=Zh(u899J7cMUD?hk=s#DfPg5)u;7%0MWF&pAf{;8RAzhY!FC z>|9*XAy{~bcYWkcObOh^b!OYYYK5`yQYmWRQi-3RSQ?jMXmvGzN_u+1w{Ifq%x@K5 z24CjDbq%=EKIP}<^I^%6V=FM<0n&p63U_jH;**WVkNbfOS{@9I4_XXg3V?bbsdG1^ zRCh7&F)SJ2<0H~PFhCHm6jq!UL=R98LJbXR)YR7(w6rh*bhmSG2%UKqIp>Twd_W$f z05(all=|WXgT6dFXgyN*^786f-jk`El4pJ^2w#8Cjxt25XfV>z(KWiI4@9J-P>l%A z5zEX@Oi=F}ob~810+k0kLuTx7+Vc$pKVexUQ3kP#WMw7&DY%Wm@A!9e!T7S$8}vKr z;qmczy>g@4(6zIsfBzh)sHx-Iu~45rApskhA8*a<`bdB+RM6L_{kOTPZE8veY(Q)` zJYkvFc8GzBmNs}ZTf*%RwsNw9h6X9`pP@_n-J=A^4|obJG6}7;waB8)zk=!iT%3R?IgS4 zqhKW5@wS19z>x3^|DE5W089|V!Y4&X6fp`wA%lB{xc8$iFL6JAe{F5;5KvGQ0{^|J z2X1F)=b{KH5X-$oLrOkArz8WVWn~Ir4n7tXgxtZK6@36j$eC}y)0AomI<$1HO7Bv3 zkE4`X=!w5~kFPqZEACo1;aZxL9AANsICA`}?Qp-NgF{DzT>j~J$upf~B(+qY=HHVG zYQ56uI);WECbbT!Tg@l)Pb(@alne}}Gmb88nepM~=H~cBL}ALvj`lFTx0#tS+q3my zNR`V|w6v1CI*A%9B{K^P5Xpam&K4?g6Jg+`BR2T%$-&Ib90`pttc!VLyAJ0{N^|h= z+|-xqSBin!3hS7LdW+>OJx${}oBdVmc(b`(zYz4by4u~w*f=}M+VG7z9ZZ%SbTm8^ z!444*RL3n~ilgtuJ1wpHGPToLk{kH?it_XGC%u0kFni==Z!aq^k5#0R^QNOijzPkQ zT--=ale`<4dVj==e^470fB2iJ%-hl!6*RLO&Jfhv--v_jL7Yd}rNfHgZJbmBa z-+$W`K?0+@ySx;XlqVH08ilq__m)pch>7h&&6?)lmaLx65eR?nZy(H5Eu;WcbIX@A zuX;jph!9kSE~VALMm&H1JZWGRU@iN@hhboFWe})7EBfpPPcN@O`>O*$`1@>@*P98_ z=j)UtB`3q7|GxF@ujN2-SV=&Kp@sYsD`4{FdMvE0ML05XbI!E!dFk^Bp$YCvO1RZu zzq;+O^i|nUZ}%^`E_Or^0a%~@=ElN6iub*-@eU1*(BJTrqoa1rN!YST7a9#rq3-kN zvZWKaBzn}&$+7Ni5TzosHX+(=O2Jn&A@5T;9y>q(68qU0sDv4RrkPN7mFI?z zGBVjAF1*S4^DOS^P9vr#Q?1A+vO(yFFyWY?wzhdoz}bE?gseCA(gFg?qKa;;STkyP zO&*wF0R2(Dy}`SdE+wN@N}x}EWD2ZBqVXd-g6Z^!--}{}B0{-au!Zm5pu`Py|A;)A zSUVV!NC2(w`B1pj((dYUk1g-DZF|X=PJ|*= zuo>5}@JJT{M{1Q$0FdbI@0U|mB}`6E{xIS2;H` zZkOGkg-_{#92eVKgB{NQJDtU$%YFOy&K!^>*@L*D2*4aYY5brM9zt&N^71|i@^AJT zbK72F)-zS%ukwb4)7V+k2lB@@k}@+1AcJZvf-Va_AZ?6{jkRCAhzFBXrPZud08<}R zR#lZ#QtF{I0P+rqJsEbYj#omK%RTYrvE8@J-tYtv-8(oKp~l)+6eJrJI3C!5GL8%O zhJTTimcF57e*1aaxt<5i@95OTgtnxlBs)91jGCGn9!eo^n2nK%iOKkMNrV(M3YB6= zkv$MoK-h#>8)`7Wovtx*s$alhfQe;PEvyy>j_09(z%v-a|7?HN4cNJp!=t0_tU(*P zc%||2@eegMR6vr#L!c)K3?UN^ifU@a$?x9rS@%=95lpfJWK zCoL9Q0>S>HAIr`F?J9?)SlX;?jRgH9CkN;K)ACzK0e{xHfRsUmx4f~@|5hm7FJxEU zKDj8qTIC7u%L5>ELEPD!qWYgfS}m{)#;?U*qz|k*0E~PA^t>cR%%^&Ai$eB=jvyc-;OxHOX%arTgP`8a0 ztaW2$z|2@tnZR-Sy1HtOjE>&=SRlH}jO$5bVq!3`Q}4@nKTcyHpMva_-Aa`J8z>s~ z8MXq?*giNTlw=wnzrGHN8QTCHoe+=g%Y#iz?nuB<7Cd^Fq1|e>n7#6vXysqGyhx*mP1RgsFadZv4lBT z*zaGT(IhU)HIOarB$7ox*=+xFpR%ZL6f-kg9lD`ItaQAHJ$yH>?g3r%{gZV~n?rvo zA4VWD%WicAk$`{zkL1z#vzyIx`q$px#Z1yc0WW|hESlQ1wy?BpTpP-1v|Z|mDDJth zZ)|Mb#l~yyaV0Tx^@AT1d~y#dY~=zR5Sr)pGqKPy&_BK6`(*WDp1&!%2{w zZFy))ovqX%rU6c&rEV?{E?8Jtn*ExuSF#>EdO`V_+UH|aQ%}wUq>`--E&h#{40^h_VD^WlZvy%N z<*HWT*;N_1Umw@E2D-10JYYnjWDtv>>2ZLhy%FN&-R&qyl={x%vz069pL@HwH!T}M&-wFXnOlN;z=S?pd#x#ZO&AO37V2dG*Yzr@^P4_k(;To6EsO0R=O~Bbq?jx9Sc^>-yhBsUcJcYXf@e zIW0)Knt>Vx`RgJuEMONVx8RF!;^R|uq=SQ0ox7fh*ZAEq$@EvGNKE*Z{b6IiKUGXs0~S*K!5War50T0tCBTg^5z<%4;VV*(abJ zf7eF~A^;NqHh%VuMKa)YH~94GdZPf{lP4W4bv5sgVe|p{B7LPv13b-|i0}JN(#Ova zBF#@jLqi9mNEx$^rdqFGyUEJ7_q}=ZCIh4ltptdh?~b;2<9l!b$YQ{T`t{p<-F9|y zDZY)B3*MJ~0lOpRx7trV3Rc_TcyoOk5=0s8B6?`Y8&?hcH4;| z5R$Z1R#s}>!^gh9?tfSrU{gQa%#^q$3%Q$ZCF1W&49~*GIaB*x_yq)lL4F+plwdfx za`%)hpOuwW3NgrlBu;*NxI8WVY3)#Z-Ueh!BP4+>BfS%!Q87I|{U8~+Hzba+YP#5I z^s6#>)ju>;L3j0%;qKjr4~>oYK;$~hmOgN!nrw9lH02wm))OQfTl)WWIf;phsbI=G z+uIW}+s9=!HG%`niPB6z$cpYpwojHDPdwBs8=|`()qbxNw)<7u-~1P z&Bwo{OMkL3Gpkuteao~qbY)<}L4jVpMsRQtNDQ08cT<&-|6J_szF`*I!}ylpAVm@^ zdHKl;>gwv!%`>Dz5ud?Nbewk{pPS2RcQc7ZFSoyCd17NPNRP$?`}QOFdM$Wp;fs0a z5}3Ekpk!p2WqvD&Y$MS3gPZ=>+A8e=a%S<|p!1F7tBaFXI0QOf3z%r`BOi%L5Vu$Q z=2kxEOg&wBr`cn4HNewqa+i_OX=i;sTEuHB!wbNZSc$GGD=RBgOkCVnS2Q0?QG0!J z(_imVdN2hw^$~%h_9hx+s;}cGQU+E#mzI{KipMw_1J2wJzg2b^ro|Iu!+A5+<{+Rt zUx$T-0b^WQX4-n)DT5$?0h-^v!9<`Z2YnzhY%w0nhD7%I-Fo9q7CA>S2ftEr-0wA zUslrQ^E`H{H{60yF7UT&2N77x za0HH7@Y!nm1qh0#X6u~%*MT`RZVtRS4#bwtsCS+_w|nv8MW|9i6#(Q0hPL;>+A~C& z^IG;0XB(9>fn+s7EciM=P$jt=@}k6Uhe4gZf)K|*H3vn^$`pup9)RTiiILH-Tm*4! zck-fpLk*C;+}zt=K|#GMjO%xLFEFh)%2rlLPqDch6Cm9C_8>-5^sBeZDT-8^r^o`e%)S;jD!(z;LY0)XFjZhqlgwj zRp~S|G=IUljzz(!@*|^~b&27F$3VHcfFyinb(PVi?$rz>^ppPHy@kq>62tuoebc#m zyU~x*SZ!a2rHqaA^d^tNdE}@5Rd)b_mVnHi+G7EsJWwA4WOKcHE{lpM9I5@2w-Mg6e64B7 ztk(Ixwf31 j`hZQK@Bi^*>r^_jt)_?Q%Xbtw=Y~`iH54l3%tHSUCdhUO literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Main_load.png b/genplus-gx/gx/images/Main_load.png new file mode 100644 index 0000000000000000000000000000000000000000..11aa6d980016fb61596fe24f284654b08980086d GIT binary patch literal 11581 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Main_logo.png b/genplus-gx/gx/images/Main_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8efaa5222bf9d1fcc09e38fc6df05448b125f120 GIT binary patch literal 22305 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 V!hRt>!ezAxys?E*wV`{`{{SH`b6Wra literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Main_options.png b/genplus-gx/gx/images/Main_options.png new file mode 100644 index 0000000000000000000000000000000000000000..9536d9f712db3e7fc2b7f797d7b9e42e32993505 GIT binary patch literal 7506 zcmY*ecRbYpAHTB`xg>;gxU8%sl)arzNGK6PRz~(ncA16jB&++H*)t(@ab$(;O;&c+ z@713_k308pkN3yt{eF$->-l_sB6PG=s41B!5eNh|R#j0CJ|*F8L_r3>3zFYR!v~40 zJXW6qetan`!{P5U&Z_rZ5eUkSe{ZDxe&6&)% zg%!>9GmI^O_UVXIzb+kvF7 z>B4NMLca`S`s?-vcg$qjYZ!lCULq zsNgtO>puL3=T5zMLq?{U(}R`LN9~-aRFX2w3J=y>f37~u>b2>wsH)0)%EEQr_{}&-GA;vNvADPjg(iE>W@cttgoPIxoG)6YWE~to#m1(AmCS=}nwLYh$yZ80$*R`&$E1_mB( z&z`Xh3Kk2=$eb<}6%`HTYNgk9F1e`<7Mo?>wCQ>G_fnVRd(;mYb@G&>nda5^DWyy7++x%Dc(*)P~@58(5D88q+ z)Ad5l-wmypi>CIDjC{PwNVUGVx2NqQ&hjlWF;U|0;bG_a_yY_EBXs7>nE~m{^&nX^ zV{dP7-0{F&vnUDo<^Jl~S<5_Af#L;mEn_(P$lxGZl=6$3SPEY{@|VHTp0Tj7KqshW^)0>A=anJtIfvlk;i;=IUe!w1A}`R7tgaSU z&C%--p@uz0&!DKtvUIp*<7Yz}8yg2RwbypeDhn}M-WOmHq@%pPv6iTogT~VG;fWCc z8D3*K*Y1h9j({^6Jp43FDS3qk5opdBi#ZdIfelbVq)>sXm>@%()x!7W3)RU)#le$R zO~`!dPy)AoPj5YjE2I5@ehzNmvUqwaf6K5aSPKCMMx$t0NT~ zvz@OmN@vEzs$!Bf4H@OLQ2tGA- z(p~*?;ETi!cxQe1p!j2W_`uh|V8A8`Pgve`uUbn>O*ol6my7tmN9!=$E8p< zMfNy}Yu8pf6lkRSUG9)%N_Z4)(**3dsJOekdu8c_lYi!=qtw>Wpc?4wQ`p8OPoc%4ft;|JYo01w+xEbFCah$ffCU? z%TKTVX4pR3XyUmAHa@t`0;$>8@$H+uxA)(Sva&Ki%8=>N@^TSZIXNVLOR~1MHvGop z?tE__ANA$sWzO=ds+cEEPBBkwOk?qLankn^mG-NvO$Ef$wXpk(!SZa*EGo7lDSU`B z)@!@M&2XZd$;ruPm#9Jy>mLZR#i_EBg`&gp-MonEF-IE_Cc29k2cXiAtxk>(MxVBQ zhnzzp!V6IWO?hCyGFa#VUA(w-flEu{_tMgHQ-PRmR#6K&CFK5)Ar}SF_3PJ7m6Y19 zATG-&Ik(#IBz${kTqr#@FmSUHhf`nKI)IP}T(~6db0vlx)>iM0`{1kz84b=qK49yR zo<%PN-=?RJN&4<@C`e}tc3TQx^pwm9zg$f#N#J0llIKmZnC*ybf8c*GmxEvtQxZb7 zwzu!`&_#;AY!mLcC~YMpLQ;gB{?UXQ!I$Z9(=lGRXzjhKo+z1;nD}g08GDsB!nHO0 z`~c@`p6skFb0NZ(<l=caopmFk^J*#e{&{PHC_>os35{r&yK$jC^V>FMeJ5bO)? z=sZ=-d$`?no=eEngvn2j3DISvtI3X464TVwBHT<-xvr2K3Fp_sj5F;q6Y(i2BW(09 z&r^mVCd*d7O*x0x)z*d*^^8+BmOOk4_ek__ohOlMo zi4sU!0RT8&vyLSW)Zkp<<>t0Qy==>RDCGH62h(|;WQqeT%t%Gn+utu@w>jMwCVjF$ zvv=fw8Xk7Vdr@WUjCPv1ZX=-fU60j~n@nkL58yUFe-S8OcS^uDzS4?c^hQmmCg>v?03sig>G5NV8yY}eI zR^;bcI!<8cKdPK2q+S2ab{^K&)!hZO7nvxT9INwas)LD2yUhND%_K%E&&O%GzaY#j zL&eAEP=%`H)#2Zj;=T%F{;l=8hU+DK%+58Y_VV&X<;JTFG%`mU>i`VYvMW<9VOEze zUCKZD8i885ojeuul~sakscn`EYgb?8Ww zHNKYeJ(=^$XwVgC-d!Dy8L=1TWu*Fgc%hnEzYm3eCDsNuKv`+Lkz2{Z*5|dTAP#8*8lUT=U&KJh6i?z zj)UQC77q#y$?x2`qX}?vq+n$=w;Uf&dl(h36ch&OZC@#FI*~Oo8ST%_&DC$3(B|ai zl*iCETa*Hj%CpCz`T19m4%eHS^l=0JUN`!^8y<|6S>c~umhqRAVY$&K5(Se9aOQ27 zb?eu!f6r1z^W?n=2?ytA{@7TIPIoE}@!$ML#z|JScy#iu8G zO@ub>?d<1IezlO2k{*gMX=WQ2hAOhl>FevaBB#8r7~%|Iwu{dF9{%KUtnY#wNHM*C z|G0e2F@_XXv&Rz|q*p+q*{8#sAeW%FbJ;P-XmTVY@g@&Xfs{Rl>^2gE4O;Ljuc)|s zx)~GTy93eDIym#I6yVOp3+Ru1s5#&kyQz6*`iyui<`SIoEIB7#pdzAFCUN^C9ieK% zUt$L@*klSAIzS@#@ZBBOZl!}`|Myi@Vj<>l*#N~~Y2~dnp8xUji+V-Z)L>#oWwdeCP{r`Sl z>dWi%l{UlR7?nL`A*3*=>O9u3sGwT&sHv%)BzOAn_#oYmnH%#fo(zpc?{4FOe4T$* zcUiAMgq9{uDJ+1Kg2)h;KtVz@2OGOkHx|9TY=`0E;*gOEz+mHJkkxE6w{%L5J`tpS zvWtoY2s4|q1^UX<{Tpa9dCu3(3tQ&UpOtJw`}3ksHs?wa|zKUPp6zDh^QMn}n! zsK=Wi&qr@oIf7v48Qh4psW7&w7#R!-3KES{oy3v3qV_)np_Sxw^qQ?dnFE3LTuAqb zefzeW8qQPG?DMwaVjVhAP~QwNhrr$ ziAs9leI_I%WaID{SkU6yTBvcMGPL{PfA@%MOr!VrJ-HLqeor*99`3ET|Eh6iC5=6Y z=0Q=+UZ;Ydv6Mnc6P3{4-9J8`oe&%Q@Ed_3GvzGKgkWKkc=r3N*tqA6pqH1If%T_b zxVkzC0Te~x`+S@t%zD@oY%F78YR5ZEpEqm3ZfesLA_cYYY^8Ph(C7RCJNxnaOD2`}a=yNj;?XaEqM~PFlanv?O-z`X8W<#0nzxX( zb*D?TQMK4?d;2BJqHV}}JiGXh74nOVo3@++4oB+-1_s*r@YBXiZ;=wDfXe>}khZV% z#Pyi=8-+zhjvoi?NHzQJY9@ACe%W5?E4A)ovj16vBuF3f)jx3B_eAsXoH4{*OixdT zxW}c#P(;&4{M&?oR&d{vA~3F8jpU%Jac_L~(8>gIBlY=AT~T{E0KI}r%$56ALX0Ql zBO_|(G>XqD3NZ#7;*?;9so;|Y1CX+x7q$!pjmyJah{J4JK+a2ND%czE- z1%Y71M-ONSC|{t@bjI<^<4kkL{{H?zGzDOBzCLg8E%E3_i0b0m+O?{yG3_mP=#+vV zi~A-(GbCDZ+>6W4=f-eyW*|U1q~w~sQM1Z66;R=(i}YR4vm}XA4bIKwbaQu?D<0wy z5I6^U!eF5jfvn1M(|uXkQfh23vlqX6+4e&BTezR4wY7X+->@_Fir*N`G)sF9Knr`l zytyEsuj8e8i?_ded!N7N(w3foR<|f`!bGhc&EjSLcY8@t^6z3c?gA}s<=d`# z!oP2O=3JEkg5#Ra+_Y)NA1xLpWD1?uP}^ZwIMDI%@0)< z*VhGI>c-@gHOTV%B49*3sb^0JwWdww>&`H|DWm zTxhtdF4zz(*tkywFrcfe3z7~XNT)zw6^lJ6s;@s<+ zt+xf(7v>=9+-_f1Q&*3nzj)DswdWOy&eYaHDD2#{+6qq(tp$)CzB%J{1(Y70((%JD zI)#R#&P&N$zc=rD`?bP6-28T}7$y{F^rai~wusas6Cs4-_qW$8uRr>F^e{U=KmRoZ zg!Rz3amd8P#OmI?d;Abfzp8idK6@$MxuK-nVV5JE2$GhPvI54}{3ZXXm z@U*~>09}rckD)ZG57+8SE!rskJ7U?CgV2Tuo1#sAB%WPxIW|9Bt(L@a}G{?Y%t(46Pi%!^~y}6`6uA8ikg)ecRZ~bBeU6qQZcW zjuI~e4P*eL9OryHT^>>nV>#4ZM^7&(M?J{`2)|szgHwJv6oL3Bv1#6u1J=(N1c8Wg z_~%dVvFfMU55bOt3*&qqWcPZ)-0LL|ICnc?m`VL`!lgDf5K`qI+#V`F2Gj7hI64Gj%t85tSV z>W&;RIgR*2;We~EDu;S2>c9jrZhtlg%%j#aaFh8RvoZ zJrJgmf;+C7M?XmFkm4=(&cAFUO0;52P`hr|&;31BjArI*)D{TSf4IdxQf_1(#|F!!3+@nHTcX0a1>$?`>95J(cbgP zkLRP9#RML2&3EM&6_IK7G2XPJvq@Pa+c@4yIW1QIQ@q(Z@8zG}K69p`qGA(dW5?Ff znT!Rq882xs**f8j1(`{&#)jm-0@ZzCZbDMTE2g+ZZC0nu1I zyP<{1M)p*DR$M;GiVi3U3J^VtUz<9ma6H>M@YH0ZFnTn|$^93-FK(uC(&Ta#>BMq1 z|Gr_nLvz*b|66htz_oAeq#goO`gi}xi1B63zV8it<0f^Uo6|dpdUBd8A81&mO-FwG z5C&{7?X-+k)6%MJ1g}jcK0dw@+2MDz+5Q+*sDZ9-+S>|0ZAKH(G<6Kn4kxtwKg zet#k^aILX`lW{Q;0QWck^=sCEwVH+Uf`Woms|w@nXqH=0G{+GU5%I09ioj#P zJQVVEo&5Zqf%5FxPKot;R|y0jnrYr)y#Bxn^i9I+*TgTH0|_#xzW&^Fy!T2THeY*C zeAfjKJsHfqJ$E;^YNR5+QOTqjkaR1EvneP2OKqu*&%_d`DJf;A+j%m_2jJZ)85h!* zmX<<6R|5B4Qw3_Mxbc}ky%Eg42~iOdx`o+UUn$FuSnLh!@1D``^FL=u`CK_&F*~iD zY-2Fn9$tMGpKD9SENbtgrPbX5D7Xi5pY=(pk^g94-y=ajKHq=t&Z!9+<%XYg!Gad$ z0#hsji^a00YH&uHzs(0bkv2l{1nPah(5&g??gAl`zyu_`5(fSz@Pum!9SM&$)1!lh zOc@{*Ea;(KEr4gxB;hubQIy!Sk%vw^adE9%(hq68T;= zLCu}=^sfS6)qq{$&f&4SmOIQA&kPy^LqkXBx-oZ^^R~ zzsPFFP_|pq3J)G+c!T^QHN@S-B;hB(|L_sKe!Udr7<=5t4@+7MHWa_Wkzku-CkigR z&7*tte0W}XK)~?`;FuCb6L3hfz!(gc4PV9vL!uri>=tm7Q`hBwo&@D=-5!yyx-my6 zey>le7;n|QJ_EzMcV!IC%w+t*1|R^1@4KTdRk6$4+}YWwLQ3>Jr?8NJV#@hD(MC$I z4T~>O#bGeMAANmwi}+nsu5FH9fufvTGXs2aKrM%=H^fzZZEvq5qpT&#K!w33dE$ADIn3iK~E(zrmvmS0f7wq89G z9n+mDbGiuL#M#5Ye>(srb?oi=h|yNSKKpyJ6l8b=1VoR)GtsuQv0;SawKHToRb5^E zaro2Y(??KeXTcIY{Bm-9xW2l&8U^;^-#8AHL4o_V+kQdlj(@Eqcrok{`e($M+L%}s(2pAJ>1LP<$kMEm<$T>(6^(FJT(w6$H5xud5?g$M_7VT2p_ zNa*MgH__KGS1%qinR7YF`0_=b8DCa#`SRsXAlj9eZdf1L&VNtF!$q&2)!lcj8vVo* z8BYUfw*U@qx8>uHVhFDU6b3PjwXiiJ>jqgytzBeA z*wSKI9s;{25}ff-x>8uHmIl_vRS4ob6cwn!Dv@Aqxl^!!A^~g(2|^O`AW8SVx4ZA_ zoc$woZ-Rh0#mF%8tvXeG?>*<-dq4d>=lssON0Cx;Eh&luz?wB{rdgI%m71DbZdq1> zrfEuJVL8mAMx#T-Y;u^yp$C1cil#Oqw)_ ztgNiKYyTYNI1WusO>Ex0nNL3Xgeg;|)R&Z$JpR;EPo0JDL%kxjg1>O(%jtq6TRk7BPk_P zN{Wk%*}8Qr zefvLvgb+B6gJoG*mW8USY}~k!+S*!q-+lM}vbMH%M~q_}sG=w=TD0iv($dl~`T63kOugL#4iM?QZPusU`LQ6 z;P1SNypxf|Uu0ymeED)VZQgt{INT7$n!6Ap{yPSE)v8sbq@*Nyz25g?`CW>lpePDm zU0uHphr`U8HH)OABmmxf?>#CjD|xfBiYF(Ok|`As0_iwlJ4i=>BfxS{Y#Wy&z_Kt+ zn-ay%za%76p5WsjmMme*mMu4n$qiGi>Bj)4rKPcU?OOKl-(Nm!)~soYqTm5oxpL+F zw6rw;@ZrO`{r1~|zCLsH>eW;}xtL#$8cm{QV@QW@qY+N)D!p2Wo?wtjFi1pIQ8b-G z!=&7n_)LRtBg#-I`R7DG7t>6ZEn7x;dHF5Zr^Z})rF3Zmz}O)waI7btQA6c-n7 z2QnXe=piyPG5}b z-nqpC;P?CQl2TGwSP1mF^MemQV9zW6%Ajxr+Yz{g0LRAd^z|jb@Fg>u1T;%Q3Kz{5 zyci0xtGAOhmzSrL2jO-cbO|{w7Z3Ro`H$cHhUVtxTh661UCE(B2u6<{O=4oAl9`$L ztZU7hHPeI;uB@!Ac!;!X*DglgaR=kPK0F~6GZaM8G^8HJG@>|;gI`hbx?BuF;Wh!| z6B1eA@nIMSC!%3`Y!f%oBW)xK_edAXULQMm?!2ytU$SHgWo2dYG-JjLUVH5|0FE3v zLRncEH8nL?Eniz(OIcYNt5&UwpWCou17&4p)YsR?&(+k_P*zq(ZEfup>xqpq{bSAk zKx3nSetteZJw4^Fa5y~CFpRi60e0@($4M@ zfk5E8%GTD_lAWDRYild5t*rnoUc8v>>}=MrUyrJ)sH#eBZ7rpxr9AS;BUi1fKhXXl z`^TnZ$Bso+)uFE5-rn+)Cr>hZ^yqj6Uw!oz(?=HI3aL0jwGU`8gbap=^z_iv)5Gat zFUNI_-$ldJhl13!x3aOTgW)LLpO}I~q04cINQo*Wj+Es25@~2?xNe|+zn_T{Co+5X zY*wyZ2{6E2SJUCchiPqX<;f?Xq^PKf?c2A<>#MG=MpacdZQ8_!4I5BZmFnv1AFT88 zW*&2m6df}K>Ithf3R=c zHiHKb1}@Fzg%FsgIiLbl*Fo1o(-0vQR23Nv(cOKKj*bpyc87SWS7&ulXRV{~Pu^s5 z-5#C~UE~8jh%N<=6lhWqzSQimz4H2f#emk-)Szh^)z#HZoH+5CWmHwAuC9*4!a@Rp z07XSbsH)2D-Miy?Vs6jQ&SvrA#n<&Lm%Fon>d(*P^ZB{~T3cHgHf$IG>FMd5Zf~d5 zk|>TqSO$)e2*W__>7}cui=o~Wa)b+y9wo(b@VmV%^rx{w?V(l=G1TQ@WP%q>IwYW= zOF@Tl@caGO4Yahhly}~F=eqL)ad1bD9AU|lCGqohb#=_1JsTkY4A z9RSa5x7~K2prD}Q#EBD3m@ol=vE#<^Ng%-N%xwHZU>gRO;}DHTQG0vo?d>I$B#3wt z2?;?|N=zw8b-Nj)D0E6mlVg(M@t_HTPf<{%g(%iZEYnxJNrl9=kg|grQ_45Pg77((ChK}eE*w}kieH;e#v8x zJ%*H$ii!$edGSTsQ_>hBB&HF?upRVBgpj5Z35QAWB%>$vg-$-e<5CD(CgDqqEvA%c zLZC~DEhSx!L%VIU^acj@b#-;r)z!t1=gyr=AQ0fuM;{%~HTeC0>g(&-v}qIT)~)+d z_mEN!SP(Hyb3lq+J9+XX$;ru`3c!K|3!Ijg7T4ardx5^dzIaSAYe$V?k;jL}ws8yt zH5#R=>jM9!1zGG*XKG?H-Ht_AN?II;`l!xH%OuO~;lV^dgWN7`B$kjIa>HRwrLnP* z+}zw7!SfHUSl<{9htYLCp2FeqfD{Uac=p+6DJ(49Bg`QqiispB`=+5L;6`DH+r==K2LM$F z6h$HE*!+(o3Aq#w9y~}+PR`9Cb)AX2Fo;AV1K`Du`#bgRx8Fully6U+I#m>( zPtBY;Q$2qCxPR-`t?_|l`}XZrR#q}OF@>crFZnJPrUU~)#F0c0goQwp5>@oYogv5W z8>ozL^t+!%>O2DtY4@#DPz{`=(R<^3!W z2z=p@QlcmdqehK-7I=O2>eama?z?1UWH5K`T!av;TD1yoXeNIjwaIsTNl+xFlo+Bf zU^k?|5CZekR5L0iEsn*hq(nNxIxoEN0uMa!0Gg)VY+gU8{sDZ77+%E;~s+4pKhl|4DTc4Lk%fu0awQJWhXU?3P3hBq_Njq6*RLOb;J|^#Z@&4)TTxNLqD71F`Fsc=XlZHTt+(D{ z&z?Q_lak2tddW`klCHQggrHM6v|AQkmPynwm^pJMPdxENe8KuwQ4DBojvjO9@$uXJ0^2;bLXErb?T#7*#ST=ZEzS-UtfQ^p`pP$dGchcs;WpzN{aU_ZEbBFIBSDJdyo&YU@v zl$79dx#H`9wr$5j|0yUo!uJRI_19msfB$~YojXTCK|y_YclX~mHa4D*NxbFn8kG|1(n;uwBGN$!ozSF62?(fQ=tWez z@KdBn=t%D(2n7Ch&v`q$=e&Jy-prjlccV>=^e=+B!5|RmA`+ov23QMV@G~(0_qcJJ zD}bTHX(26`fa@ufeH8G{?1jMKKp^nWzd@r_A)E2<3%u@qyt$_%-XH7Z05Zhd`FOfJ z*t=l)^;~=${5^eKar}n&8wt1Iz}zeU=4$&mVDT=V9{d(A?hYVHSqUi_2}z}!eTWj0|Ogeu?#M^m0FmC zdq`JNF1i+yZ1d|hWcl!>W-#s|+Rot!}x8f*;Bi$$szE7N-mfKf{O9t4r5($L%roep!3RUyy z&-6!XBd)ZRPwqcQDl5eY3Up&(*Vq{U z{{4$0%C4r@huM_jt(Lz;b2ROK<2icTGW(LA#d341eqY^IcEnVpND!$%+=J?)W=2K z+}t`COlE0mDTG3ySO(=4$Ijy@kJl$Wymd#zAzB&5BHTPYx>#&}S5FT+U&vAZ(K~}N z-+bX1E?!w(gBV_FcG&mUFr#V=>K=*vZB2F0bwrAYi|d&} ze^gqX7-XzErE|$=yAXf8$8vE+wEybQ61jCN=5<`$sRBPAe?eUx7cvQ9Yd8@ly!rOyBPGTEFX4rEl1`Y-(kqECapQ=2ckP@bcQPfS zcj<9IQSM7;r_A%S)2#MIAyL*5NmjfSnRs63y#TE3bht$+Ge{Sw&SyI1);lM|qYbm< zRZ}xFSMl|aP?^&7Tx&9|XUDErB&<>&6=>pY6Et5c0!WQJL9?V zVsX+j?MjESl#oy)c{(U|e*Q6#1&=Gq=e3_Jn=HAkL0*Rxe;G;1YDRuq+aDDeK4g;Y z>TV|=S#LRv@e)uty#PWhdPJ*O_at&fYv|-)H=`2aC=HN&o496`TmwLxiA2s!?}`ushOV$S!>#{qk6 z+UA9mlMjFpGrnMcI~DpCCCi&63ohpRZkNp8!w{mq^JfWizQu9mdjX9O{4?RC zU6T!wY$H+Rx2b#&9jv%59&85s^;4NS25%}uIs zaT}J0G!A{kG8oQvM(uo0!-Rz0O&X-PD7$G~1Uc)0eHp@nXV=QI~ukx}nIJk9C$u z!sL34w)hG%=Hl%2+~7*ygd#;)HB!4@-5xx&Ve*169adNd#$Yhns=hOwpX_z2Th;^`n)-JppKRrlNNNx~`-o^2-;U0ylR0|WU-M!YzQuzU7Z-O{3KKr~Z(G}T)ka50+tDfyWzIn& zxO1OO+B&-Ffg1QZ#8c3O$Tq&nB2eL#bK<{E|mB5a~OSs z^i3_v2@ipG!NKr0*6l(t&1X6+jFqN1R1(j?`@b*U&*&JAT}sOftEv(JIl;lo;90O7 za{qBa#h~xAE=2pRaKPLVqATzDnNoLm_cD=4oZJ94`fW~<@vCOf-QC~qFLozSd3Rnz zWk`m`^C*0<>ty3)V>G_~ppS3C5M`)6Dhowx4_jF1YNDYjiCPHei}6Pv;?yCw)vXD| z!w0;oK`968W66LTo1L9Cr2nH0-VWxD2rUqv!Px~s*gB2#)C>&_Sjx)E1}=<;Ll8+i zmX<%t+wyDzmpK1yOlWIq(I%+uG3A>?0n6+U8A!Z$n~;X;YMMdaNZ^>4|ADc>;2_~w z*TGmiT4y!B{7{-FXJ`IK*^2G45-kW*)5{^P=f8%y!}N@1JJ=3RsA;0w`H7tN7{~K7 zYEenaJvn*#vx|C7=1K5qK-cE9c+GvT0LUMRfCKsrXsi3bvOJRj@7G4lk;caQrckYX zNK8STG8-K&P-hV&(ygH2U`%t+L59#kD}xn_b3m@DqN20X$nyT~YDwM@g>tQC!VO~u zbQ-Ow?dGCJY8OGEf9Bbt)nc--8WM}W!4`R8Sk}ee{Vf30o}RlvtLp0Rz9A+SAI%|D zK)Q8R!up@~%T{|v{Qlj@2ZzHn`iTMLqi}g3;U1TBK>T&Tl~I${(>(*D9OawEMmfh8 z=H|mKUK6g(dPbF%m1<*ygAk?XXHNlzsfWkcjFM|=YIXn|d;eZBC1z#4bKJlyBaMsz zhKtmVy+TM!^TS1*vVx7r^k4t^k z8~5(XKmE|}L2d+Uh|L#|pW5B)l}OIX>9Pe~oCH{Bw7I!?KvqG49J!w`;;Vjz#j~{XA=!gUo(VarYPTJnn4G+8VF48p5dj1v z5R$t9ipWzwz1s{cZEc`*ajSyb+EH)>7HGOfxCpGu%+S!DLfzTb0EN?IHoa%x>vm56 z?mxVvtb9GuAuxMpJ00MJ3c0gw-8uK(k&%(Jm6esPuCA^pRb!0{0R6hpsVF@DqrRXd W80(LEpa}fSfsndJI+a?sFaHnXISLy9 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Main_quit.png b/genplus-gx/gx/images/Main_quit.png new file mode 100644 index 0000000000000000000000000000000000000000..00dcc7deedd9ecdb8bd01b2b83a638a76e8e2a78 GIT binary patch literal 2242 zcmV;z2tD_SP)`H z00g3cE&%}x%5t%-rjR&3KKJ5 za&mL;J$s-1?X}NZYp=C-Pk(>E;Xp);#WvURi0g4b7UB-9Dy8%d z$2fY1N+=>G$Uz^5>5|Cy7>{l73bY>5i`7_;RalC9a2tMy$4V({hBBVUgd$>VDS^|m z3tl57)C9}%FZ>yo;hs{;vrRf`L?|M5!WZy@ z`@k;ooRrqrODQ+iX;_O;L>!GX@b+56YmR^5+ohDtyKT@lp@=vMXJM~F{(cTCs?R>D z1bVDj3}d?;&>(mW=i%aR-m9(%MZ_Vv0#n+4UWI>4EwvC2;2BA#PinLY*bg(XD_&iL zNIO>G94W0AsrQK39tU9YCTA`pcEq`DWY*wLT!VQPkw;4@&upaqMC>bx9WIyaq?&{# z;7d|kKW^)L8yr>jc`zR6D51(&o`+9YKh4LF@N3L3rPLZ#MeaQ~RnBNntqypyYJWSX z;X^ncudM!`vr$43(OcboDYmFcd=s~nQif!WBVr#pacocWFzPyM~M2yG#u0O0u0%G(THM?2b`2(>)1is5ky3fG>kjTIK-Q}xcmj*1*F6un;1Mh@rL61JK}2kct>kKWqugdp z!|SDYKS^il{R|&ycak?;a_`jro@EQXs=9W^Ea_}6mtMx{nA53)Qp##+<)6gE)pDMI zt?@b>SoOQNlwP|gT!bq&^!Q&OR5_yu>R#L%Vw?|C!V-K#I?n^pE}?@kx$Yn~z&fcyFU8G6>`N)-dAXbyV}3;ZRlW|ZN-6gb)~21% zO!-3AMZY9+Kd#0Nm^0Kp(_pAx{w1C68OsZrXQq5X>te0kL7suRrIfXsxPP;vC82#~ z2zN|_KKk)QDW#(Vc&X5GP7k%-kk-W*OpAzV!!n{FqD5$?=Gv`S8pW?gMAJUHLPYEq z5mP%3rt;mUY3_Nq?84FbVr49c9T9P;j5wXy>AqeW&zj=Jd!r^V_gOfx3V#g?B0{8# zevw>B9leiUe9S;~-6ta`zryo1pFd8{;D?8URHc0nld-{lWQ6wOPHlQ-%$U)#7yZ(0 z`2nuP#4n^z_s>mjHLB3=bi7%ihQ(pzP{G8rQs-0fs;c7|MD6WjW@5g+eH+TCU!X36OP5nYlP4C~~s zcbRlRTSk10bUr7_4c~^w{SP>^l=Am(9#SViG*w1AXUna_OMz=}b}40kw+-rM@FvQ4 zHr^#{~-^#7_R9EXkeKOj)Oh#>5v4|V6ut5}Q z0ER7CUwH<*V5&?JhV?;?UP+`+CYBe<9c__za7Ep0;Knc_vJb8tE7%G}19jXryD5&`8H9p^=VJLL(icgho34 z?+Ded_NWRXjL!^JIu1)qDc4pB>DjV!WwkuZ zH@>=7;p%P+;+vGO?12kqLBvf4o-V#mR-sIl$7uG)$q}(jMRZqrI%|qdJOD32pdl7$wx57Pf){00Bf;0W9Q0Ij~8vk)9O QtpET307*qoM6N<$f^=dW1ONa4 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Main_reset.png b/genplus-gx/gx/images/Main_reset.png new file mode 100644 index 0000000000000000000000000000000000000000..fc28747d6f99cbae223109b38c187520461ae8a7 GIT binary patch literal 6399 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 M07*qoM6N<$f+rLde*gdg literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Main_takeshot.png b/genplus-gx/gx/images/Main_takeshot.png new file mode 100644 index 0000000000000000000000000000000000000000..963abab6f3707ab69be04f0fc9dcb4bad7d39eb2 GIT binary patch literal 3544 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 INQ} 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 PBpRY1tMZ^&#?b$NlWw)H literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Option_menu.png b/genplus-gx/gx/images/Option_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..6df9dc9bc640c2fcd1b4a3030f3a3ad2dd586ede GIT binary patch literal 2482 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Option_sound.png b/genplus-gx/gx/images/Option_sound.png new file mode 100644 index 0000000000000000000000000000000000000000..bc0a856a8521a30fb96e38ad27fe3ad067e9aa08 GIT binary patch literal 4305 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 bq6&R-NwDhl9XbpCT!8eov07D{jt~9^RJ9{i literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Option_system.png b/genplus-gx/gx/images/Option_system.png new file mode 100644 index 0000000000000000000000000000000000000000..aef047a9ae7b07179019f39603577f75a47aa773 GIT binary patch literal 9709 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

&p}DmESI>nB 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 A<^TWy literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/Star_empty.png b/genplus-gx/gx/images/Star_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..746ea7111356f71bde8030924d41be6eb1e8ea40 GIT binary patch literal 812 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/ctrl_gamecube.png b/genplus-gx/gx/images/ctrl_gamecube.png new file mode 100644 index 0000000000000000000000000000000000000000..de72f951c8a77eeccb35a49e3ac9a44d542a01a7 GIT binary patch literal 1310 zcmV+(1>yRMP)4 zrD#}=)9@+Q;3Evr`TjTtqwx%;V+l53E4E-=&P~VDxH9+jPmJOCII%y?Sn4@cjYO)d z>V=E(06H-XzvEZ*#<4gQd!QX{8Kg>sk_KJagyo4f9h)%(`y^H$T#J`VDO=E#&|ut| zr}-BBa4?R?PIk=r3t!_WtjEz_2&AGNZ8aKL9)Mr6A(A{Cct#_ypf! zEmozq`mMyMQi`^!s`kPd3~VX!9K3^h*i&@Ndb}YzX?vpsQ!?NnJce^|4qj>T9f&bi zRqY8^VQDSf^%#dkFjx?8f++U}JcKAj$MSLyqA9O z5^V3xiD{zCZqa7)2X@gx8pFu*=e{j4}XQwtod!C z^*85TE=j=1tx-JndIzW(f9S#tR{t1rAYOl%!+iMsfmr`ymrOYg)yoZ-@W>r;{ zAp9ouZOa7y%1y%rc^}hF+@*L`2xLQ>h6tX_6?eZo_R2)&#C}%3+z_G z(;IMpCbW^@z-;`PrF{!~<0QeOvvDLo(@fgiv419aK-v)Ohw^Q0wDJHKUrPxfKPUY5DoR0F>m_tyfp+N2CTt~U3S zAa6S+<=l&T<;USZp;N6`Gc(q>j9oI9ruS(f?iKV7yL7Tq^e@U8JquEuj2@PIyR6$o;mZ?kkXcwKZrIhl5P|;KIL{(L1LseDB;SupJEfPdsnpi`G z*e=ehe2?9PcD-9lc{wYwuV$Utc0HHqet>7?NgCuGRP!4ocvJA2;N8l^zr5zx zmNDuvH)JlRXx4?b7}6oTxiS0MrB(3Mr!W9Kk+79n0MY- zcpiOP0ct?IpnY5GHNSrHKh`$Z`{0FI++T1(<3tUqUw~oT3$~+7yqya&_IUL98}c^& Uli|8R0{{R307*qoM6N<$g0uv19RL6T literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/ctrl_nunchuk.png b/genplus-gx/gx/images/ctrl_nunchuk.png new file mode 100644 index 0000000000000000000000000000000000000000..fc9ea5ff0be3555c977c775973a66f4c5d9957f9 GIT binary patch literal 1329 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 literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/images/generic_point.png b/genplus-gx/gx/images/generic_point.png new file mode 100644 index 0000000000000000000000000000000000000000..eb79fbd4202cb14c5a95ed1f96851338d006361c GIT binary patch literal 2200 zcmb`J`6CmI1IEY8vN0xij+UG&;&p3|F*j?jGUc{R%~8h6v0P(`EGb9h>kcu=ZSE=O z>&lgpQoSJxQ^Lx(@Bi@q;dwrvADr< z#K{;X{HY?f6TL8$K#}do2VHnl5aaV=TSLJc^qdQ6L^A@tv-!4-x$GiI_kS}>Cg z?YX&!3X;&`aRdm8_3%Cazsq7?neqpx;QSvx%xT4S(FQ28Ujik#qTzm@skCvDf3<%o zMLO&Lt)$Qx03DfKo>kZw$gQJFOHNSd9Vs_Hyy|^{8-W=ZNZnU30o&Y{tKTz9y(PXa zb=f>t!}mlIjx_Wb zh+^@#NoUxysbSQHw451PEF0OO*kerLVyM(xu6zfex(EE42N!eY}8O%g)@MyG$ZeSy{P+$zHoe@u(nQVq=g%9RQq&B>rGEj&p+XC zCHYMA#jg5_=$Mvh9M%4{gm6n#CZK+I3~~24<#n0f?nt&FfHj(@b11J9JcYs&2+3S7_jjl3h1esIh3eDdbshGn+>0uN9q*&OhQJ9+iDK>KmQn&sTW)lt{vzyZ_9W~{6{^5YVXvviK%;E@e0!@^NTunWo}QK z$D(@DoU(|Q!u$@GAduH^&}ie`l=Ln}NVSN`FcEOz*q^Q^XCu-#yb_BL!N|{o4TffR zqbNmqPf+$4JVCalZwyDRk2K~pC{gDXa^{MgOD4+u}CN@DX!^x`yrqMT;4DcPgmto1t9 z1URTk{>{ZYgsiezr}W%s0<2aoYYY}+_@^SVrlhZ=xnD{aS$gssb6Xon>w@zwM_TD4 zPM6-RS({0dU-7m*OIQzRnrul}HumKA%4Ed&e*4Tg+!o^rdu?;+(lNy4Zm_WYzQWGH z)xpJ#1k=0bf%D5~kB7RV!I?dLw|=J~>HMtNHU6wdRg8N^S{ zurjj>v@HZNq4n5dUz~F&K6xbPFBL+&>AiH282O=HSXV|^7Ori;H?duLhmK7`)LHH` zrz2UQZv^$73PkO=QM%grkPLr}CmQ+nCof%ex%uxL%MEMdYVL!)@L%gV53DPAbF&d9 zjD{&BResteHvul&$}n-oOj+Xv_KlLV5m3I}IIu+Y;#M^&R2DXF`MHz>e*$(TXY=FSqCe*tID#sG=)seI~`kdJntw{XN&Y3T6ILyRA?%9YLQ%aP<74 zV>acAj*+IBU$l5agLCBP1$y&*&=&jjV4A|9g4>ISi!Biz^-D%6zi9@*qNYz}h&qlj zOaE>8#PW=z1((_yMhsPOo2!WzJ$>^dVfNsZeOo?f;7z1r7P9;tB(r!U$Xw7oDCoQ# zVP7cJyW9GoBiO$%&F`uYju + +#ifdef HW_RVL +#include +#include + +extern bool sdio_Deinitialize(); +extern void USBStorage_Deinitialize(); +#endif + +/* output samplerate, adjusted to take resampler precision in account */ +#define SAMPLERATE_48KHZ 47992 + +u32 Shutdown = 0; +u32 ConfigRequested = 1; +char osd_version[32]; + +#ifdef HW_RVL +/**************************************************************************** + * Power Button callbacks + ***************************************************************************/ +static void PowerOff_cb(void) +{ + Shutdown = 1; + ConfigRequested = 1; + reload = 0; +} + +static void Reload_cb(void) +{ + Shutdown = 1; + ConfigRequested = 1; +} + +#endif + +/**************************************************************************** + * Reset Button callback + ***************************************************************************/ +static void Reset_cb(void) +{ + if (system_hw & SYSTEM_MD) + { + /* Soft Reset */ + gen_reset(0); + } + else if (system_hw == SYSTEM_SMS) + { + /* assert RESET input (Master System model 1 only) */ + io_reg[0x0D] &= ~IO_RESET_HI; + } +} + +/*************************************************************************** + * Genesis Plus Virtual Machine + * + ***************************************************************************/ +static void init_machine(void) +{ + /* system is not initialized */ + config.hot_swap &= 0x01; + + /* mark all BIOS as unloaded */ + system_bios = 0; + + /* Genesis BOOT ROM support (2KB max) */ + memset(boot_rom, 0xFF, 0x800); + FILE *fp = fopen(MD_BIOS, "rb"); + if (fp != NULL) + { + /* read BOOT ROM */ + fread(boot_rom, 1, 0x800, fp); + fclose(fp); + + /* check BOOT ROM */ + if (!memcmp((char *)(boot_rom + 0x120),"GENESIS OS", 10)) + { + /* mark Genesis BIOS as loaded */ + system_bios = SYSTEM_MD; + } + } + + /* allocate global work bitmap */ + memset(&bitmap, 0, sizeof (bitmap)); + bitmap.width = 720; + bitmap.height = 576; + bitmap.pitch = bitmap.width * 2; + bitmap.viewport.w = 256; + bitmap.viewport.h = 224; + bitmap.viewport.x = 0; + bitmap.viewport.y = 0; + bitmap.data = texturemem; +} + +static void run_emulation(void) +{ + u32 sync; + + /* main emulation loop */ + while (1) + { + /* emulated system */ + if (system_hw == SYSTEM_MCD) + { + /* 16-bit hardware + CD */ + while (!ConfigRequested) + { + /* render frame */ + system_frame_scd(0); + + /* audio/video sync */ + sync = SYNC_WAIT; + while (sync != (SYNC_VIDEO | SYNC_AUDIO)) + { + /* update video */ + sync |= gx_video_Update(sync & SYNC_VIDEO); + + /* update audio */ + sync |= gx_audio_Update(); + } + + /* check interlaced mode change */ + if (bitmap.viewport.changed & 4) + { + /* VSYNC "original" mode */ + if (!config.render && config.vsync && (gc_pal == vdp_pal)) + { + /* framerate has changed, reinitialize audio timings */ + audio_init(SAMPLERATE_48KHZ, get_framerate()); + } + + /* clear flag */ + bitmap.viewport.changed &= ~4; + } + } + } + else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* 16-bit hardware */ + while (!ConfigRequested) + { + /* render frame */ + system_frame_gen(0); + + /* audio/video sync */ + sync = SYNC_WAIT; + while (sync != (SYNC_VIDEO | SYNC_AUDIO)) + { + /* update video */ + sync |= gx_video_Update(sync & SYNC_VIDEO); + + /* update audio */ + sync |= gx_audio_Update(); + } + + /* check interlaced mode change */ + if (bitmap.viewport.changed & 4) + { + /* VSYNC "original" mode */ + if (!config.render && config.vsync && (gc_pal == vdp_pal)) + { + /* framerate has changed, reinitialize audio timings */ + audio_init(SAMPLERATE_48KHZ, get_framerate()); + } + + /* clear flag */ + bitmap.viewport.changed &= ~4; + } + } + } + else + { + /* 8-bit hardware */ + while (!ConfigRequested) + { + /* render frame */ + system_frame_sms(0); + + /* audio/video sync */ + sync = SYNC_WAIT; + while (sync != (SYNC_VIDEO | SYNC_AUDIO)) + { + /* update video */ + sync |= gx_video_Update(sync & SYNC_VIDEO); + + /* update audio */ + sync |= gx_audio_Update(); + } + + /* check interlaced mode change (PBC mode only) */ + if (bitmap.viewport.changed & 4) + { + /* "original" mode */ + if (!config.render && config.vsync && (gc_pal == vdp_pal)) + { + /* framerate has changed, reinitialize audio timings */ + audio_init(SAMPLERATE_48KHZ, get_framerate()); + } + + /* clear flag */ + bitmap.viewport.changed &= ~4; + } + } + } + + /* stop video & audio */ + gx_audio_Stop(); + gx_video_Stop(); + + /* show menu */ + ConfigRequested = 0; + mainmenu(); + + /* restart video & audio */ + gx_audio_Start(); + gx_video_Start(); + } +} + +/********************************************************************************************************************************************************* + Get emulator input framerate (actually used by audio emulation to approximate number of samples rendered on each frame, see audio_init in system.c) +*********************************************************************************************************************************************************/ +double get_framerate(void) +{ + /* Run emulator at original VDP framerate if console TV mode does not match emulated TV mode or VSYNC is disabled */ + if (!config.vsync || (config.tv_mode == !vdp_pal)) + { + return 0.0; + } + + /* Otherwise, run emulator at Wii/Gamecube framerate to ensure perfect video synchronization */ + if (vdp_pal) + { + /* 288p -> 13500000 pixels/sec, 864 pixels/line, 312 lines/field -> fps = 13500000/864/312 = 50.08 hz */ + /* 288i,576i -> 13500000 pixels/sec, 864 pixels/line, 312.5 lines/field (two fields = one frame = 625 lines) -> fps = 13500000/864/312.5 = 50.00 hz */ + return (config.render || interlaced) ? (27000000.0/864.0/625.0) : (13500000.0/864.0/312.0); + } + else + { + /* 240p -> 13500000 pixels/sec, 858 pixels/line, 263 lines/field -> fps = 13500000/858/263 = 59.83 hz */ + /* 240i,480i -> 13500000 pixels/sec, 858 pixels/line, 262.5 lines/field (two fields = one frame = 525 lines) -> fps = 13500000/858/262.5 = 59.94 hz */ + /* 480p -> 27000000 pixels/sec, 858 pixels/line, 525 lines/field -> fps = 27000000/858/525 = 59.94 hz */ + return (config.render || interlaced) ? (27000000.0/858.0/525.0) : (13500000.0/858.0/263.0); + } +} + +/******************************************* + Restart emulation when loading a new game +********************************************/ +void reloadrom(void) +{ + /* Cartridge "Hot Swap" support (make sure system has already been inited once and use cartridges) */ + if ((config.hot_swap == 3) && ((system_hw != SYSTEM_MCD) || scd.cartridge.boot)) + { + /* Only initialize cartridge hardware */ + if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + /* 16-bit cartridge */ + md_cart_init(); + md_cart_reset(1); + } + else + { + /* 8-bit cartridge */ + sms_cart_init(); + sms_cart_reset(); + } + } + + /* Disc Swap support (automatically enabled if CD tray is open) */ + else if ((system_hw != SYSTEM_MCD) || (cdd.status != CD_OPEN)) + { + /* Initialize audio emulation */ + interlaced = 0; + audio_init(SAMPLERATE_48KHZ, get_framerate()); + + /* System Power-On */ + system_init(); + system_reset(); + + /* Allow hot swap */ + config.hot_swap |= 2; + } + + /* Auto-Load Backup RAM */ + slot_autoload(0,config.s_device); + + /* Auto-Load State */ + slot_autoload(config.s_default,config.s_device); + + /* Load Cheat file */ + CheatLoad(); +} + +/************************************************** + Shutdown everything properly +***************************************************/ +void shutdown(void) +{ + /* save current config */ + config_save(); + + /* auto-save State file */ + slot_autosave(config.s_default,config.s_device); + + /* shutdown emulation core */ + audio_shutdown(); + + /* shutdown audio & video engines */ + gx_audio_Shutdown(); + gx_video_Shutdown(); + +#ifdef HW_RVL + /* unmount all devices */ + ISO9660_Unmount("dvd:"); + fatUnmount("sd"); + fatUnmount("usb"); + + /* shutdown all devices */ + DI_Close(); + sdio_Deinitialize(); + USBStorage_Deinitialize(); + MOUSE_Deinit(); +#endif +} + +/*************************************************************************** + * M A I N + * + ***************************************************************************/ +int main (int argc, char *argv[]) +{ + #ifdef HW_RVL + /* enable 64-byte fetch mode for L2 cache */ + L2Enhance(); + + /* disable DVD cache */ + DI_UseCache(0); + + /* autodetect loader arguments */ + if ((argc >= 3) && (argv[1] != NULL)) + { + /* check if autoloading from USB is requested */ + if (!strncasecmp(argv[1], "usb:/", 5)) + { + /* reload to IOS58 for USB2 support */ + if (IOS_GetVersion() != 58) + { + /* warning: DVD support will be disabled after IOS reloading ! */ + IOS_ReloadIOS(58); + } + } + } + + sprintf(osd_version, "%s (IOS %d)", VERSION, IOS_GetVersion()); +#else + sprintf(osd_version, "%s (GCN)", VERSION); +#endif + + /* initialize video engine */ + gx_video_Init(); + + /* initialize input engine */ + gx_input_Init(); + + /* initialize FAT devices */ + int retry = 0; + int fatMounted = 0; + + /* try to mount FAT devices during 3 seconds */ + while (!fatMounted && (retry < 12)) + { + fatMounted = fatInitDefault(); + usleep(250000); + retry++; + } + + if (fatMounted) + { + /* base directory */ + char pathname[MAXPATHLEN]; + sprintf (pathname, DEFAULT_PATH); + DIR *dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + + /* default SRAM & Savestate files directories */ + sprintf (pathname, "%s/saves",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/saves/md",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/saves/ms",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/saves/gg",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/saves/sg",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/saves/cd",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + + /* default Snapshot files directories */ + sprintf (pathname, "%s/snaps",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/snaps/md",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/snaps/ms",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/snaps/gg",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/snaps/sg",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/snaps/cd",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + + /* default Cheat files directories */ + sprintf (pathname, "%s/cheats",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/cheats/md",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/cheats/ms",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/cheats/gg",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/cheats/sg",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + sprintf (pathname, "%s/cheats/cd",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + + /* default BIOS ROM files directories */ + sprintf (pathname, "%s/bios",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + + /* default LOCK-ON ROM files directories */ + sprintf (pathname, "%s/lock-on",DEFAULT_PATH); + dir = opendir(pathname); + if (dir) closedir(dir); + else mkdir(pathname,S_IRWXU); + } + + /* initialize audio engine */ + gx_audio_Init(); + + /* initialize emulation */ + history_default(); + config_default(); + init_machine(); + + /* file autoloading */ + int autoload = config.autoload; + + /* autodetect loader arguments */ + if ((argc >= 3) && (argv[1] != NULL) && (argv[2] != NULL)) + { + /* automatically load any file passed as argument */ + autoload = 1; + + /* add the file to the top of the history. */ + history_add_file(argv[1], argv[2], 0); + } + + /* automatically load first file from history list if requested */ + if (autoload) + { + SILENT = 1; + if (OpenDirectory(TYPE_RECENT, -1)) + { + if (LoadFile(0)) + { + reloadrom(); + gx_video_Start(); + gx_audio_Start(); + ConfigRequested = 0; + } + } + SILENT = 0; + } + + /* show disclaimer before entering menu */ + if (ConfigRequested) + { + legal(); + } + + /* initialize stub loader detection */ + reload = 0; + +#ifdef HW_RVL + /* autodetect loader arguments */ + if ((argc >= 4) && (argv[3] != NULL)) + { + /* assume proper loader stub exists */ + reload = (void(*)())0x80001800; + + /* return to loader when POWER buttons are pressed */ + SYS_SetPowerCallback(Reload_cb); + } + else + { + /* autodetect HomeBrew Channel stub */ + u32 *sig = (u32*)0x80001800; + if ((sig[1] == 0x53545542) && (sig[2] == 0x48415858)) + { + reload = (void(*)())0x80001800; + } + + /* by default, shutdown system when POWER buttons are pressed */ + SYS_SetPowerCallback(PowerOff_cb); + + } +#else + /* autodetect SDLoad stub */ + u32 *sig = (u32*)0x80001800; + if (sig[0] == 0x7c6000a6) + { + reload = (void(*)())0x80001800; + } +#endif + + /* RESET button callback */ + SYS_SetResetCallback(Reset_cb); + + /* main emulation loop */ + run_emulation(); + + /* we should never return anyway */ + return 0; +} diff --git a/genplus-gx/gx/osd.h b/genplus-gx/gx/osd.h new file mode 100644 index 0000000000..4caec0e8c8 --- /dev/null +++ b/genplus-gx/gx/osd.h @@ -0,0 +1,86 @@ +/*************************************************/ +/* port specific stuff should be put there */ +/*************************************************/ + +#ifndef _OSD_H_ +#define _OSD_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HW_RVL +#include +#include +#include "vi_encoder.h" +#endif + +#include "gx_input.h" +#include "gx_audio.h" +#include "gx_video.h" +#include "file_load.h" +#include "cheats.h" + +#include "config.h" +#include "fileio.h" + +#define DEFAULT_PATH "/genplus" + +/*************************************************/ +/* required by Genesis Plus GX core */ +/*************************************************/ +#define GG_ROM "/genplus/lock-on/ggenie.bin" +#define AR_ROM "/genplus/lock-on/areplay.bin" +#define SK_ROM "/genplus/lock-on/sk.bin" +#define SK_UPMEM "/genplus/lock-on/sk2chip.bin" +#define MS_BIOS_US "/genplus/bios/bios_U.sms" +#define MS_BIOS_EU "/genplus/bios/bios_E.sms" +#define MS_BIOS_JP "/genplus/bios/bios_J.sms" +#define GG_BIOS "/genplus/bios/bios.gg" +#define MD_BIOS "/genplus/bios/bios_MD.bin" +#define CD_BIOS_US "/genplus/bios/bios_CD_U.bin" +#define CD_BIOS_EU "/genplus/bios/bios_CD_E.bin" +#define CD_BIOS_JP "/genplus/bios/bios_CD_J.bin" +#define CD_BRAM_US "/genplus/saves/cd/scd_U.brm" +#define CD_BRAM_EU "/genplus/saves/cd/scd_E.brm" +#define CD_BRAM_JP "/genplus/saves/cd/scd_J.brm" +#define CART_BRAM "/genplus/saves/cd/cart.brm" + +/*********************************************************/ +/* implemented by Genesis Plus GX core (GC/Wii specific) */ +/*********************************************************/ + +/* 32 bytes aligned sound buffers (8 samples alignment) */ +#define ALIGN_SND 0xfffffff8 + +/* use Wii DVD LED to indicate when virtual CD tray is open */ +#ifdef HW_RVL +#define CD_TRAY_CALLBACK *(u32*)0xcd0000c0 = (*(u32*)0xcd0000c0 & ~0x20) | ((cdd.status == CD_OPEN) << 5); +#endif + +/*************************************************/ + +#define VERSION "Genesis Plus GX 1.7.5" + +#define SYNC_WAIT 0 +#define SYNC_VIDEO 1 +#define SYNC_AUDIO 2 + +/* globals */ +extern void legal(void); +extern double get_framerate(void); +extern void reloadrom(void); +extern void shutdown(void); +extern u32 Shutdown; +extern u32 ConfigRequested; +extern char osd_version[32]; + +#endif /* _OSD_H_ */ diff --git a/genplus-gx/gx/sounds/button_over.pcm b/genplus-gx/gx/sounds/button_over.pcm new file mode 100644 index 0000000000000000000000000000000000000000..8c4d88adbbd7b9f5537aed1f7b0938b66103131e GIT binary patch literal 160 zcmW-a+Y*8>3`7q>DPA7^|Ic#$azE6bCwrX~}L`@ literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/sounds/button_select.pcm b/genplus-gx/gx/sounds/button_select.pcm new file mode 100644 index 0000000000000000000000000000000000000000..d58260f856d21ea85ed9e8796075c3c3e8b8c433 GIT binary patch literal 11904 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 O+n=-FI`4x(hyMjg``rit literal 0 HcmV?d00001 diff --git a/genplus-gx/gx/sounds/intro.pcm b/genplus-gx/gx/sounds/intro.pcm new file mode 100644 index 0000000000000000000000000000000000000000..1cee395cdc72be6069f57808ec3036d2b4352420 GIT binary patch literal 56186 zcmeEt_5T*t^Y(TJ-5}B_AtBP;-Q6H5-Q6HvB1kt9BHaxV(%m5)ZujnahR>hzyuSQ) zbHDdKb7rooYi2R*|Ni}-2L4Y2|EGcf)4=~};Qvnz;HSBX^e3Ws^2HzPyg)ltBwOBp zW;S<6Qkz8F19gu|cy~0+t%N$EyI3c37WvtquVG$UIju5}n@%ucQ@e{c&{-nSR1vW@ zToLcZDk2j#;YsCyyk;qtpJx{_|=7l&@F3)vz z89>DyHU~K)?i5xGvRlXCb2C82S$ZW_BrN4zaZ1J0<(q(t*yc1jPZb4EKrL4M{Qo+Eq}-0%tGwl)x-0Vqz$P04V-rhU&Xig$v~i@Xo^ z?}_{(3o(4~YzV0u2MKd?M0JNA3e-^EC z7u(}}ie3ly8Sk`mkKu*bOG0XCl-hv(%Qyt5hG+)nP=)C|cmcaHpklFdh~JNjxMj`J z`axrS(h5*<5}TDw$A7}!U_VlimF)5XzXhOR5!Q%(Ed4Cc<@bdP;PVr@6S*k55LEY{ z*}gW;tt*{|Q~P2mgLTf2_TF$Ae;iOz+%6X^q_XqXg$MFjWf8FfP|+-^j6UI?=lgJYZWnG1+^0w~4cm_Yg*7J1@w?Q& zsA-y`uaB ze(~44}-ey zud$v%MTifjgQ`p&xKDq#wttEGUZ^1cCD&BSF}Ml3@aLfu1WBi*`=A$gbM03&T{hTT z;Tx->zFyC5-bTv+6+S)={er*7DIBL=d5W0$ivZQH$UMRYC5yb5D-yhg`^=u>RHxF^hO#+Z1R`b<4ex)I|XwAQ*kv1-x^WkFKQ&49J%%SoyfD?bYF zqQ3wYczhYJL1m-w5|4ro`XQ$hw_3`B)wMtB3$znPO1}a(6*3}^Cg3IUQ`j4FicnC& z$$#`!MrWjOZ{-)tO0g2Y&4dV?v?4FYs(0U;&ry%l$S-nASYPuRnpELYt%r6 zrBn2EFE&)DPh5KdwqNb6)+FX*sqvS19ili}O*$kr3$nwL9cf)op%#`;~Sz z?#-D>54E89k?igk2B{X1V*Ian+P&qpHb+?HlNzd^t{~3%x9!H(Qtt?UOgtp7M?<|w z#P1?6cT%#-0f!=pea5gD5%VdJZiiR$+nE`hfE^{Qj1QV~wCq|+<5MVcjX|qc`WPaylB}Rb!%g}W9 zxwXKq8#2^#xs+HcY92hM?@DdtC(0-}6Z4%{3$(Zqy(4GPeW`hfb{m><@Qd&byV`%M zUjXmvZe304iV(4wJQ#*|#WxWPmk?giD| zUCy6YU309rh=DqYC!z&T1*?HGH9o-RmNhO#&^tcIO_R$hb(H1eZ=_&Ng}i(ppG*y- zCz0Pr+wHUF<>VK!I(fmFqK$I&8MIV%xK`>rJh4|RvbTvHNoc+ z<>*TM3voD8*`;&?jS#D-KdX6#rTA8NqE^$ZginvZ@#;C}tp{c!`%7|9$*h*c%emXE z9(J~1ESXKXD`|L&;7_Wylw0YlDspeOWK;sqQIj>4Opl;Cpl03}tCu^De#1Qu$Lf#2 zN@3-Q4zp103r(>_*kpVqftU}%Sz#ra+Cv@vXGs(bB_*O2Y)QGIa!bu2QPetbFQB3x7E=K|jLZ;c zaWh!sg7#cX`jC4~8xB&8b~>Qh!YhdTwb2Xg0RE9G$PE!?z7?8lRPZLU)06}1St+Jx zM^(+r1|AMpy z_-DH=pyDnO({pGNZy)GRF=yuXMHJ^H1T0^gjp!(Nep_TM{dKK{?F5%v=7r4hL zkqP_@+QY9>*ejC)EJQ4^J#=Ez@om&x?uhV+FH5GfmpRqx^U5CeU%3ubH9l%T*UtFk zu-f4UcZl`exL}p{D-qwTImNu;c59|J!2O7_GK#2*eX#mTM)tLQT-~6K6E2V~{mfrc zLG)#6&;tH_nA64WKmE5%1@emno&yr5_OfF01;_*352z}-Ms%SaJ{0C~g|Tl;Hz>pp zSJ$YM#Z~0I@PL(49~-4cyMsQ?cJqxf&0Z2_r6)m@`RMgDpV_&67oX2|6EE>=k_p%_ zfmI-yDSNozamgVd;ufL)VunzuQ3=1Tv�PU)T~@5p(BPDU1`rVd9!}1w1}iG6gG3 z_FA>P)8GOZNt0* z9br3iA2&j3&Nhork=ev8YHslUZcOLofSF3e;$loCCO7eSoXr!RNzQ82hPf2g*8lt} zh4nBlObbe=+#nhz)v*7l^?Z7f;AOgu@7aaOT1ss-ktZ;BlO0|@y{uggwT`EGHLP<+ zWpkf*6?GO@%bns!RzvGM*G=xxP5GWuC+beZ(R-!$>H)Cx6sl@eLECPm#9p%b=)t%U zGHz36w7V03N2l^OXwYA2Tin*DGYkEsloe@7Yy2KlPUtV}<4TaV+-V-i4pqmfbHp1| z_UNM1R$K4BMnP21t!Zx4AKNK|&iHHj0RP^BN> z15w?d2B_FZ@$5jVJrr|gUCJ5bS0n!;n%WcoXOHjvPk2Wj?7`hk$|hGyfxRYHPI!mA?zrz zqOcWPg{R?N8d1D@x@7 z6%FE&Xe~98A0tlXQ!)*cruI9msoV)HyM!%?>iY+cYX%lssGEPmCiIiW8?RP8mtCmH z*gw|K=2@`EO*#$tqoi^l&=j(qI71x@8g5QgNqneiJf+vMD*3ljPobcwN5##e)^7hlyb4o=PbrOHE}|Or5a}t{=WVj%NWlp@YTe8;{PZwo`&zT|Fyga3?M zuf9>9@~?3-^qnQz5N8&a6(UX+W3Jxaejk>`$4e=>!Cp1vqU}ZX$bqaR(9$Ss7J9-i zmVq@;F0h~QA^u}6hckp;&($D1MrYkgF5`UkTI1tz-md)B9_E4Y2$711{unADGk!}x z;{TLN@PnA+_%p9XJVrbV_SnIWK|6w@)>W;MKLlGAp0PLS^NkGds%R4VSh`Eec0=IK z_9fTp?Cg3`5$_V?@Nf9($|ra>2Yn2^bfLxyKC>p<5APXFbB?-IoYVeQVs4VlBteSe zjvQO$Ht`9df)7uj67)f_mgsZCnT+TkuROj4a?v>{4Rt*}?@us%Jx5dz>lT!?N^2j@ zj(++0JkwAridvhkEXKcvw`Q7gWu+{_6wD*;iB(m=rbv@nF}gKpDJlq_mBykyuLJH!4V^%hI9o9L!+Zgct%wTmhUEKxLS z?d8|o8%}Z?E%Ig>kFA+)JU=1begy3*#Nw3hE7MKpccFv728neG&4o z7*#Jc!*zU3(CH_3CAtxoc4lhj?Zw#odWYAWjQe$i`3nfc1>B6P)TU|(|^IxD>j zSkL&S2^ELl+AE5>P?^OgP*)5JIwh|dLpmyD;v}XN{&TQ|_*to}_7s{BO`}eJHt5pl zM7i*#!E$q=KEYwa@>sy;#NPTfgDV(M^=H3fZ%`a?Ka;42)Ef+gYIr-@6QlhnE<|l$ z7ymLzk3zQ?Lb8E7rJ({HgaNBWRww&f5I?zMY7wpyHpn}t2j()l1U#`YDueD}4ADY; zEO*g8J-weBwPij_yBNsA)-|>t<6(27x8CHhH8ps79n#092Y))Nuo`fq^X53mOA@-1 zSO^$n;3K`C&~x;JI7UtO!83_k>fih*ysN*;tfe>lTD{{l!jEVIRu20hWmb`M1A22O z*~kb|CjN~H%mRhj!+7O5Wguyt&D6?A^;_yQmW1P-Jy9vpcp5vCeJ7!*C;SD-?$ZSwOMF8)aWlB>Y;~ycis%t^wHj!XF$O$wRs^8MMqxQP;2dMfV@{X&Z#tjYMtlei zHim!0l_zq>1p?0qHH;qwzd8~h7BzQ}-$t6JBJVqEPxOdt&RtTQimx?8`<$dickww? zjLm>dMaXldS>%i`hh0e96##21)QFBGW3U70E)ASIH3}qb9o?qt3Hzjb2&(ZYJ6Db@ z1pMGcdl=~FcfjT>9L1U3QSM^)2Ve#toA1IE#8n%!0gE1|7qeP<5zs?iH{{N3{|&H*%a7 zMlJ(!|ALjD#VxR_ST=l#^iFMSLp}`h6FvB$aw^u*pXxQ~KJ?h6Vz|t6w1zfB45b}; zEm`j!a)g8fypq=6UN0goyG|?&`jJ70yHFLZ8hL=u9$tnj=&CxJ>z{n%Trke-D~Vs> zZx+R=u=&8RE#$YWC`=C+tAW?z?o024Np54%p}?QWHx^ z@H(e4YKRx2(Es{n3>{W^dQpIzmcGNxPeE5iWlXB$)3MR`Kw-B!-fs(tnM8dS56WA( zl{R#tL?>!+G%zUa?KMQJp0og-$P?pEY>$r~C^@CkZeG6(wE}wM8!E>@mt+i2x?{(v zK6LLGBCJ1ODa~aK$6FQjd&W1YGk8?rq!9iChOi@CE|^$AcjrDOhl}6KFN7@t^fyU5 zdU!n8cl-wCA>Ckr+h=+vs=LX~7}OOqsVI2sHYaiZqBv8TCX_OFg9T4xUCHD0GxWh| zYxNYT3wz=|)?fNZeO>^SlH?`x}tL41k3c=(=pg1y^{hn_@Uwi`K>hVfBGqkWg>a{GycUMqL*Q8=>_`3 z?)25W+?nDYc;W%DCwH;7R9<nOlTcH8O}?{rrI;pqYh$|ebevg^w;Z$=|RFB z*iQdvn{eI`rNKW=+hMYRyD2V}yUNE94i>zQRubLmGvp+1xt0zut$a(gb-L+y^>lVo zWstMjxH-*0LZM+e_8Z z0QUv;y|`F62JW>xEf{9V8Obx5i)E9DP$DNo~Mu8(@dq^Ef*oJQvoT+(qBVPq=OMyF@EF{tMS~x*5K+ftLVdHT^8sGW%7sO3WvVVbQ1*cUjH@Jnu$2 zhcON;xQ{qSPo%PkrumJ>i7DwV&KRwiMw|E1TCiXtU^PeK6N$e$M>CBU5Rb$j^(jGa~Hh3+DX9f^k|s0Qr(Lm!d~Nhi8|~mX#i8w*k%99q*B_c9faY@ zUHuok6fp)m70-ERx|WKvK-6v(`u0!O%%Cm3SLs2u^>M15v|A~x%;JxQd%%Kw@IBOR zx(?dnEHx(+vxHCKLA@8`t0DeVZW~x|G*%ryNTg(jil=ziC5p0{&5ZJ75= zVMqLWo<$@pq#f#92z-O^qol`I7VA@|;a5NKsnn%vYOZgbQFrXJc*XFs+r=Jk7P4<+ z!$2dO{hn4M=!=drC*@95pTJ{=%Nx{EN;`I509nEtPqwA!kx|^(X=Yi(WbTp&xCg|H zj`Hw1LEd%fB|ehu%{3QGvmIT@n!&VC^Qx7R~XVt0rKJ*8X zn*JaR6jG7<%rICh0uGh$=_tHuG__2uW;oM%ZvJOHbQj}r9y8X_&F4;tnzB8mUDSu@ z7W-N0021z}XZSuuiJkP1^dq8R$T{6?54V^u4pjM|=?qDJemq!kBEs2~Nfw+#_5`Co0$jjh~ zyKL*YDIk9)RgtMerirS!ihVRb$nNo>dH}=>jj}U+!Ge{NL)c+zAU{sn!u}E-u{zNw z)fMV!{w(^_v9$H!m*kzd#(H3swQEE&|56ddBjypiPWYbMBvcaXC;NyV(n$4&dWcVh zVMbPcBhj8YPTr5lxWC#?P>4+tPt+hg>Un~^&XIe$dqT{0MUTvj_#Wk% z`bunwPxn)3&%IpetsmO`j7nC%U^rmxARsq|wJYdLR_9*A#OpKq01R9&h;~nvIu!eq93ifAidc-hPiC;I#+~I+5Y3m9 z!-7vnM{6Lu7H)IO8WYX5egQ&JJCVqGYAL>q|HB@an$QQ6LEL`jAv`gJyy3%^PB@h1 z>1pV-=R4<}wYWeD7StP%&vT+H`~%1`PvZyp6}GV0gl|hX^J@A1#AaasRdn-cs5MXD zm6VT1y48&Tj1ul=R8Y>s^>wD0ligQX4d$ZQnJ=0A%w+x_0};?8qA3uyNu~+&GoIGJ z@4Rt3#>MFgF5n0d(=do3oD0c8`ja5T962l5M!EwnY&o_-VjH;)gPO~BCCWjK$~tR& zjm{g6*Pv%Gc0@I)73vl7LHrgqpmPb=guQG#^wz#i)m1O4dAKjAgZHO))Ljdk4{5F5 zdNsR5xQc$Iq>JtupX}ptewycANejuGSSXfIeZU@6nf5X*E54E|NDhh=H-q!my+e{H zlfEAi(=r%L?3atGCC~=o+dc?|#PO_7d~u#(m~v4)Axy`@;76m7>7timWcSw_n0JDH zz;>v36Non#!gZ9)T2d$GG@8YyQ0oI?ZW2Ac1bluTw}d(ow{@Gif^z|##vStxXtb3# z9?v8E2r*-Ow3nF9*OM4-IQ7M!9pc^iP(zw&QWT(9*hUL&|G)%sneC0?EB=Xzfiwm9>r!vwXC7qWb41MH!)f2keoJ}+I}(~=7?pb3+yp0 zC1kf_fS8YX9dEN%7k%VclGB2{P9e9tGbd?;busG$Vjc#ch;jn(Hh7xw0J%o2D^+E$ zP#?oINh8@(*YPv448daaxK1S(lSQ_vZ8N(EtuRh_Le@76T8pE5bW!$addyQ|WLEHo-lv=QB7zfAS+&nXP7jW7ZDSQI*(f!er?KL6Ey;*kq8V zl277U#vSJ|w}dSnKXCdwJDe-t0DR8Z%_E2fmC-wfR84+Ua2O5X&dbC3rOZscNKl;x zHco0omXA`pFq?KS;QRegMkdX0kHt8hpWp7aH){A@NrD{$JjxL&#@mR$fX!LhN6Tj~ zGRHF#_YR$P(>fX4oX!DsDB7({kUgd+Td2PBMY&H@EH1{9@&Mr)W05O@M--#JlDE)! z^whhj7cf8JzeIh_R$6nXR3s3MgsRav{h>PxAH{ay*2sgoiI~Vk52co6BCMM?NPh}; zs)axGa@zgfdbSb0M9qyD5c52)OcoYPtN)+^VQw0epm=6G(^aD9ST$vla+0|Q4D&fN zh0dW{2(yru$yyQ?z*N2jW*X(~z33#HjVmt=6Mx03GY!?OfSAMhn2<4)c&~7rO6xDO zSvR%)#eahRWgmfU`{`Llcq5CglXF=4Lq%Lu8MUST`yiL=~k z?RLOgeT_VNOPCY3VlJrrS=f8QvI}eFSG>xsB^pLGc>py3)h`mPi-hGoO8ec~M4XGN8g;b; z?u2LneuYaN?9os7GpLr_6uyzth&zi`@--lj{XrK%8zG;3q#6sI(I;ECGdlm->B61K zT?6tU%-LH57rkET8`lU7W~Gu_oWeGy^<)FSL3t|wO5P36c+ZSF`b<1GDr(wVK064% z+O0zJQorriA~tjLxL0y3(LoQG>gr78DYFe*6x=cQAye!?Oms_IEu5Qn4(||_&IT^g zTA5@btMEP5VR&_4pj3IRw4c4l9Ks7COgf@Gq#s7V`hBdt&=1o1T_>GJS$%_NNfWvq z@tc{|&V;Sz`fv}Ve9AZYF*2W0NIl9m!v{wjt$)K+B1V_FtL%X~ifY8*@ zQsOsuj+%--?KQ>oN{!^p+;%oK`CI&g|4sb^>a=bCZW|aO-zFD&`?Vp4=D&)Ykm+dF zK4Vr*TC?|fPD}@^^S{^(sVvx>Bzh){bKT3uf6u-R^P4yA6OL#di%&$^wHx}Oz{7PW zmAr{R>t{_e2rHCP{9d*Sy*TMjo9b0TMVb7!E~izuUy&ce%X$ZWySF=937gT+{PqSG zUS{s|orN;0%uPiUzZjy@Msf&JJjcmMCql;fi1mZ@)@fv=3$)~rv0eM!Pm33(Iq`zD zGF%uI=UOZKg(vJ7<_=bZn5w*&Xzbr0ulrEnW2`17Bf)sBopC#bF)B#ch&$=0{JeB~ z{xE+@X)4}A-!MO^SLG7a5p+K=?7jGNaWuBtE@q{6npioY`mybS5UYw|6{wp0Q~5vC z*n2>)Rz^$d*(dB2Vhu)1u6&sYf(2e{m~?DF(+Se1wW{{Vuw!hJ>#;k=DQ6zpmA}Mq zg58{wm_v%nR%IZQ7n>7JaVEyc#YN-+=cw7qk*r_rL1?lEvDmJKGLXl)eDWu9lluoT zPF^mT<%Y6ns4s};eHEwch8?`6*4L=Lgv#aa*GgN%gWuvD_*Sxzoz^Ocv-~pto>V~X zNu|PaOUKks>^{77yvJjME<#4;ym!kK?U8m0^JTm!%Bh_;2gNJN>daHgWPkNCqqNd@ zN>RQ6dzU!@b;3_-fA(-R+S?4-sFgd5x*k&6MW{sgM03&KB=RO0E0U_*JE4@=MqR}o zOL_>b`i}2KaLFS7g4dd@!uJZtnwhOL_7F2qurIk{OxOPn9}?&2cj9;9o#qF7xtYP;f@QbMX(#=sL;<=gZ%R_U#ZS#PP#%cg zxlG(>azD0Orlq!6PS18L!uH}PoW`G-|LK_9Gu$3m$1Swn*y=T=9pR<0QK=vwMlSiS zVnN@O8J&p!@EW4Y;tu??_1-LD4>gC`na~k$E9hw-UWK~NEtNXryWEMCp!Ao-Kys1vQ-=A>N>exl^(3a%*`kuX5|y zD^RmlX1jo_lr3Ry9nK*Cyh~$GP7eOtX5O8 z3U)53346=kIh^a}H!y}-6RmDWzaUON8J*4P$q=dpvtRg!YwcHw&WY2NM*J0SHm4B^ z*;rY|BAB&Iw72V%Y((vd&*;6(uKvM@imTv8IL{aXJ4cJfj-stD5U}`nwuCy7yNmZr z&PKWYv(yA(Nz~ssYreGpGRn9gu&y?vo6%(Q98-wjD8S~BzXP@fPYQo>3;3zj0PKUz z!-n5Dcczoo=w&V=n&BNy(J1L%3a>|9v6;zV#*?5qmqy$o?o>=^AHv9SYFc3f(GX>h zvj>H+=i&%tnZKI(VY_>fT>{JH4b=RgE}5CW%dHX?U>V#~^d4o0xQ*M-Z)A2NTc{vi zgh}`_r@7g}XqvpH3fr^w`tG`L0`#KKu(S4ws3g}PW-Q@Jbct4QZan6%B(uc2$m2VUi$m|^WA-(6+W*cCp{l89zD{N^=agP7Z2818`j^~J2ryG> zC$Gl$yBjngO@%u&M-8!zR8bXKTg>7~53Z=3*6*rsSN$w^w)|vPNv>xk&E% zVoMR(qckq`?ea451wJ6aoF3eHX|#DEW|(DCZut?^KJQ_^t5LlSC1|PsL^klU8L8dn zFq5#7-{GAA(0`I0ZX>W`Zgzj& zwkDp(*R^;>u*P_(g#f|GlMJ?&M=BGAx3{w$`nFiF+@yILhw72idl48H{p z^=1qCIgP|9BGnUC$1CxE7$&q8EvPMqGAU(({|zM0MGpuc1f}(V17Mk`<)LZMiJqFkv_M(%)yw`cn3_k~iLt&qfYcN!bXf|AX!$Ga_m1 z_XH+mlr^Ygws2s=%;b$G+rJ03K>xoxHoSk)M+wMGp#T0Dq7S3r;SH^~!t!8(N$9o6 zNno4Y_(&`b1MeRgv+WJk8p)CvXOtN*jiY%%Hfxi49IEmRaaQ}Nw@VJ`;`TdgiZE4a z$ovCnx`iF0=it!G5#6LZ;Q+(cbD>c%VJnK)!s=5mK>t0>x#TYCg>)fkq-|o-#^3vo z?DGbrwi3F4RZP<9a3b9k48vh|5jFuU%buo0{Hg7Qp z+exlf&j%m%al{Jgu-rZV0BA~`r1R%H8}y>$@6!8Zx>LZJ!=94U*+Yp6!dtnw2*2sL zSYzrrx!1hs=T{~q=?qQBe3-41?XgLC8e+fl7lIBSuOZEoU*kXmllf2{zpC3%r(ln1 zIO^rhu+PAIVauJ#*dIbDXP5pnGgvs5h8j#Qa`M?jl-cNpnMQl!!qkH4jePuPJdo>A zFx^M{rAkVB@-KJ;X8`t-&$_4dHpDu(&2%TQixALbdA}x>5J-W%!_A{-M1PVIUCbM5 zT$RV*r=UyTX7`lW@;A^-{3Je3yudyIOWqMLD#vMHDk2Bp=s6y%>q%GWqAhodwF5zy z5w49>30EYfWDlEz3^X~H-Wbf%+lr;h$ULC+wKBmrKz^9fMtBjSny?Zqxl=5nre^mT z>HUnb&zjQ9Y|IZJ-jPSVj8^OToVpJ656cQ2<%~*m^gYO6kOk@2QFHAJYcLJ1PFh7X z``34%&_sg6Gjjh)t@HS+=6ag(Fc(xx74nuF-8>h^K@5T6(f#aKb%cHM8zWJH^_t1tk0V_};=x_aoa^Uajn7`+(<7 zBAU?;v2Eu0aJ3}5U-{=}@z0>EH+WgR7ky4n6OYs{v%I=XIu#EET%8XexpS>!7Q@|B zQia8=EUwO0lE3$Q(9h))%2i%9>RB`Kh~9@EwJUpNrFs52_|5uZH9*sG>=?e7iljw& zU#%wHQk^Sr`8umXgX7%pK!|DcsaFs^x>~gzhyFq7?tdm7`K;m#t?aYB*66OI#WjFW+E zq|A#(;m_sGu)*8aZwffRK=*)MKf-DxR7=Kd=|CU<2#%Z;WNzYszLH!hoaEjb4FMSI)YWt|>!|$;cHhl#yg}# zYEL-_f<7gFLYJai1!K(1WJG?^AwFA(t`0KX#hZ||ghISwmkeIZz{oN$UD3DzOw~er ziE+z6sy?9G+k>nz$y~7_<3yRn_v&=n#bI(2PNhpw`@*GGW$Z_$i;)HT%UuM_oroIP zzhnk}tuVm5?>?3D0v=oYd9+(N<`1-Y8hgCXlEuxoJ*!xphd;$zVL9P|xF=l{+G4$pR&x!^{=jm~#|}Ym=mYuq9iL0s7%j5%OAO@nz8YlKS} zuzkWT=q}0VoYpKp5Z-ebW4beeA(X!EF>_b2pQWWJ8UfqAtGkJ>{|2kxS# zJC!f#eg|lp6jzsT2@O#Nq7GL;cuRaTN^tO-QjVmR{!{QJuH>{bX4%Jy6R>$!+nnyN zq94lnlg)G$H514Zc)(JVF?|QMb8b3i*w6l|uLunfh%Mz_iHkpDcZxKf#~8=Rz+>>} zw8^-qlDWaqybxvB0PaT5qfaXo)+-*kk34zX0kDGpBorJT0!G&SS2U?khtS zj|9}eXZBzp-TU@m#4^<6>u-AJ8K?r$OKc~zUF^cna{8i|z|gHCmN^HELKx%KH{P2q zqM9m(r#3N{BMu4^*hi>=Tn4m$8jXQ0--XSK|LRq?KcL1quxa2))v2)%n+CzYUJh|K zm&u^?5b1htwJGR`-_a~%Ob$h9G&RXooEG>-ez4FgsU?YU8v;)S+N;g3BdU34 zoQhE~>RS!oG_>y#w;(p1N}kix#GTxf=)6Bit*vgMTl!}}hS9+;bG?2)$jtX+HM6$8 z8(Ypzmei!80KTOZBYGKxd!3C4J0+UIUX`Aps$d1AmLbUAgrex>+I1|N+oB8TQC;OuWGgdYZBfW{gHr`>q)=qd$$U$;5TeW&5!`X7uC%i24 zC;TR&PP=pUU)asmwqTQU(z!%!cIJU6aflW#$oZpXWNxu9f0L?hpApIfPD({@jK|Jo zl+xa<4R#ygxH8_kW$udGFsFf)eL+o8CqtgH1E}YjKj=+iS7({ij@ap!0Z-!M$NU8K zQnZ{P#1z5^da-kx9r=|DjQ_TlnRBrm&K|9uQwHTxIs@vdr~%Vn?8W>;jDRT!Vyi~* zMiljm*&0=J`a6BGwBc9F7mil5P=Up*u(QGxe{~fz0pN3eoBB25GP1%3qVoqsid0Zjc`V~!KM;d%0@lhB4vFI?5 z!U)cRsxIWTXXpXxo z*MmCvDcq(9Hr=QlPT{Ykz7FQ5^STnOUKKoP7g-oAI5!%|(Q*@*ggk_;O&=oeN&gU3 z1;0dJ3|ik7rlkL7cIpdUjq1cTmjA_5auCs^efUW0n5zl>u&quSS9IPIWlhkA+lnZw zZ09nCX_+MTkTL#ldQ!TG-^1<$@QEl-yqX62jMnf zi1zM})*0a!LUEcqj~yBB3A_pB5cm*jkvJ~+mi}2u&#k96`bVX|)X`Mx;I012>4ifCU~+kc})F7#K{A?#0KxYE(T zOg>jK@SW)$!7QN=V6S=D(41;^#IM?IKtlu3G~t1L&Z>@Y;UuXAw~T0|&QLX~VK`9# zky}JpaVOc1{U|OJ0P4-(&|40e!=N^iMSdXEVPJ3j>pnj7Yq-M}wbw+qukV_=wUX*W zdT*7P0-L}U5W9##G> zD~q6K(`P05Y4F}8TarndEj3{|>wHl`bDqvwqGa!vUw z$}MDxIpE}TsI0jN?GZ``u2l%;F0EnP_^!4k{*KxO2(186uN(OX-kxB;2 zb?Q=(OUSMiVb@bf;`!m7K~8?vLEj;rqd&dpWca2XgWt|=dpb0^pRtlB0w#E%2& zdj^-W&P;zj^j5LM`25N{Mj)SoCoRDn`oo+N5`%Suee3V6yzwX(_7eQH#AmUE*vP%W z>{L5*2bp(qB6d~!pvQhq*rYs94l;XaQa6JI|PjfbWOzb`fbdPMp~+cT@p?%pO8!~ zrhc{{}P$Frpg`fIgweNA#`PT z;A3cD42YF}7wdPe4AsY_2qh0dG+M!QIbLh&_dTN%}RotT#<~nnwPENNJxn&JAPf>I^(ngx7a%9?!t#cj z{1j5AB-W2umyCSDvY<6o<+Z6pP#a?%@kOFzoeylT7Ma{wDdXV zjebQRM%OB-qj$4@P}l!Xyd%GjGz?~Q{9bc>%ZiPx)o%HBM^6d-U~{4m`>UZ(thaSY zD=bY)92vTucsFuD*~Kvv#<=mG+KVA)<|h(D7hDIlcJ}7-&6Q zfx5ZLLi^RYK#Hgz(dSs}z^lM2+=B(}IJvr7D%3etAe1$96m?68x0Xs})NTGhZae-t z=Ab{n-bWn=z8haLGTwta;S6o)e1Tbi$i2y5u=9yE<;{WksDUwwynwGq)JtsfCQg4+ zOP>|qpExVjJFyI!9Tdh5`avz>pTg_AJSLg{i{4yUP=T1%G{*QAK9jHlo#TKXnhAgi zj1o73tLeMrn_BP;jsr=_J0}8^ERpQd(<* z|Ay9pp8d0#HdLOhQf~QDQemzNjENeg_w>C1F4;@==OvGhUN})C*TI5 z6nsG7JTTjY+yHlhdAf|>V|BbraLXwWEEk%Vu*F^FWC-5JJC%!i2PM`x?CTqyU!U%; zM#}2Ne7aQ^lyw)adh(FqhKS#7<8X8chyP8OZ7|iJ^ir1qm*4~7|`qv;oph1jT%bz(3p_n=68;Y)8+~5 zqyI=$^_YlnAS)MBQZ30HUd4T--NJ?7Ib##v8)rqmgn0g4IjMEls)Fy$yO^pz>~E%| zqbs83Ip@Q76ZeKM$)6*?5??uQo#ni*Gr{QR+Z8n{W?i722MCyUS>)uyygo{4sZwxX z;>BRm@C9@%;Xccx?AKzou}&_$HfEx)tv`?I;z`jxy-DGdiC*Z1w8(l9{OT-rwt5C5 z;h}ofsIxIGqi(QtpssH#;`w-1fi6{8;!IFU3<_nySrRojmoiHYYpuNlynD=0-vwVt zUxuni_vXvPheEkR9mxzYHkjT?>)dp=^H8Xs+9T?FOtR?1e7d&T|4zK&gLwew(F=wi zB_<2*3w}k@06#%WNtJ1uDCbU#cKl6zM?vu(i5iRq@I*&ls1%0 zP9Mdif5+5B3*@O$RnRbAi(eFteM3N-cO>`%5VDNMA>*TbP}9`Ic#+*WD&+s-8}Hwb zru!Gte!G4V5LLulHvgl_qD~V0|MAyI#cuLWV7xbMqe+IiI z;)LaZO0Eq5k%C$QwL6WoltAaeG+)g?F?>T$s}zl#3>6QRaqCF6gLTYX?hv~RR0-?F zlBg@u55UQ%tvDO~kaS@mfvtJmCpmk9WfOBJw0EPt$)S$)gVtCrA#F7;`|?H=^JNc= zqob5w+8SeCC}*gWJwP6qxX3u=F153QXyCWEA*x;U%b17ic=kGaIX%d(iWlsj)*gCB zITMQ{)V6-|_le!e1T9|8DR;0IslB2e_|gQX%GKy)-xl+HC@NIeN+C}VF9nB;{dPWf z%lXHC5||bJB<8kW+cTrq%jMWnag{e$N}#X7T8X(5ni&jDNGyV0YeUuY@;WE0)Hb@E zFJ+*&s^Wd%l~Oh24;3_XOB>9R;eqaMyNx&2yJ1cP1^c_0tG@k=`d=!q*;z3|MA5JG zL-1^3>V*E0b~tb18~#V@u8x#vdqr{P=smt-f!x}B)DHSA`9kSJNsW~>iBl%j)g5JT zcdPJ?k-vH{`b*3;|1l=?KERDIMGLm=OZoD#OM#eBpxf~DbsuncprWhaM+yc z?{FaaBH=+OlQ4~=&J6XG7AxmNZQYCDO7p}&#&-u50u2zjkR={9kO-gxiGF9EGv6M7 zaz+lxi=uDFT!`}F-gKjXmx$%f&@Yh&5X-;8Jwab$4?f)PYPD5UX(Qwq{L(2MaQyZB znf;S+YHcc+6HbyiDRP^YB>fU|+m9V?eHK3qn>>r26>~7EA8mx?z)In;ceo_qsg<_s z1xE#|1V4M{T-W$VDX3kMlaQbG7JpU$8{c`qO?oSt}U@X@53``yk1luLJztXm4Z>RzT$yWazp%F`)U?SEE^&AQ@X}jU@UPX))5xX zbmw|tQ_Oj(h{vY^+kBPUExDjHm;?68fvI9V4+%xUP*5b3@^H_mBhkSf z!9J0mLb0E?Wwpv`b6OU+@JrK#hRTI}k1w)Ih$E({1^1oG{wltY`dz$S zjwO{sZ$j0rw%%KOE1bbjaNgTf#5`v`X$}Zma^GqSI#1tiai3SkcX(KOWp4_O51t55 z@uo0geo^XZrD$`q-m9Y5@jvt}@nt0IX+EiE_);RX(s?OJ)kt0IuUo}#%b$AtNepN(E(AXUBfKX{ zX%?mVwNvyZIm#PK9RrViC4Kd!ZD@k>$lRQG+8pE-!I|ya#va)37O`rgvim&{9aGdl zOUVfA<)GA>&A{bRVRR5#i4B79LyzobD7Qs$Dea8Zn9LI^u@Oam6@2C8p~$Dau;;;; zs;eWPyB_?-*4y{Ig(%96h3-gE|8r$IDkuMi8M+1CL)*nVGA7h8_$YMQR>cu}n#iav zkS>u9=sF?FHcip-ylU7_VP0Hfk{8}Kb?~EQ%7NBv`1)e38!zki>fRn6e z_>*(T8Rf17cPs^g++Ug|v7|Bkm z^4h+q{!02INs2q9;muYlU^u54ZwHi&04r*bsK}-V1 z!*SBw4g`CJW?L#N&llK1K98)8_?$&vJ=DaCu>x*ow*vnzHi-sNYoZFPE2Nqts6HYU_)83oIpk-z zgG)lyVD^0mt#usTqr4z(NH0`Dni9CH{|BtuT;i%U*UTC|>2&i-ibYORBjT2F>+-H> zF8dM~9W_QhFD*n}m1gu6zk-X4140qo60-oty~CX-f=)^NM8#wtDT-^50fCSnhB4QO zY0_}Z4v%qic_sNCFRKybrgwX=5YEJE`94Ser-r4SIJGoY?#*9d4JGHb(X&wc#J%P$ zx4IbPE*8(!zJU$7lcbnzPf)jEr?|yHnXVT#*gc{zP%D z0F0SH4k_nEN^}#of;HM8yezR1aDwtdRbGaDQNGf&7*Kxk!EgDlsTHM^C>t5fdWGZd zW!_k(h#HZuz-$6dDo(;nDSM&|YJ;Rzq^YK7u;GL!UG~jte4&uuaWp= zrnW}AM_5Oc3vDA(G}TK=o#TQ`kTK}S5ZHjfKsyp?4&CL+Odf%tQslooF>okPjrF4 z$7_}Cfp^kAJP)VxEYi>IE^}(3NWN@_DLnouSKqGl2-bsIoqDo&W4lRZ; zPkXai+2AcZ%zLm{QrXRmXOQ%0DeXxvOUyM1Ct%4QUnXWr;#ka&; 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 + All rights reserved. + + Proper (standard) vorbis usage by Tantric, 2009 + Threading modifications/corrections by Tantric, 2009 + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + - The names of the contributors may not be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "oggplayer.h" +#include +#include +#include + +/* functions to read the Ogg file from memory */ + +static struct +{ + char *mem; + int size; + int pos; +} file[4]; + +static int f_read(void * punt, int bytes, int blocks, int *f) +{ + int b; + int c; + int d; + + if (bytes * blocks <= 0) + return 0; + + blocks = bytes * blocks; + c = 0; + + while (blocks > 0) + { + b = blocks; + if (b > 4096) + b = 4096; + + if (*f >= 0x666 && *f <= 0x669) + { + d = (*f) - 0x666; + if (file[d].size == 0) + return -1; + if ((file[d].pos + b) > file[d].size) + b = file[d].size - file[d].pos; + if (b > 0) + { + memcpy(punt, file[d].mem + file[d].pos, b); + file[d].pos += b; + } + } + else + b = read(*f, ((char *) punt) + c, b); + + if (b <= 0) + { + return c / bytes; + } + c += b; + blocks -= b; + } + return c / bytes; +} + +static int f_seek(int *f, ogg_int64_t offset, int mode) +{ + if(f==NULL) return(-1); + + int k, d; + mode &= 3; + if (*f >= 0x666 && *f <= 0x669) + { + d = (*f) - 0x666; + k = 0; + + if (file[d].size == 0) + return -1; + + if (mode == 0) + { + if ((offset) >= file[d].size) + { + file[d].pos = file[d].size; + k = -1; + } + else if ((offset) < 0) + { + file[d].pos = 0; + k = -1; + } + else + file[d].pos = offset; + } + if (mode == 1) + { + if ((file[d].pos + offset) >= file[d].size) + { + file[d].pos = file[d].size; + k = -1; + } + else if ((file[d].pos + offset) < 0) + { + file[d].pos = 0; + k = -1; + } + else + file[d].pos += offset; + } + if (mode == 2) + { + + if ((file[d].size + offset) >= file[d].size) + { + file[d].pos = file[d].size; + k = -1; + } + else if ((file[d].size + offset) < 0) + { + file[d].pos = 0; + k = -1; + } + else + file[d].pos = file[d].size + offset; + } + + } + else + k = lseek(*f, (int) offset, mode); + + if (k < 0) + k = -1; + else + k = 0; + return k; +} + +static int f_close(int *f) +{ + int d; + if (*f >= 0x666 && *f <= 0x669) + { + d = (*f) - 0x666; + file[d].size = 0; + file[d].pos = 0; + if (file[d].mem) + { + file[d].mem = (void *) 0; + } + return 0; + } + else + return close(*f); + return 0; +} + +static long f_tell(int *f) +{ + int k, d; + + if (*f >= 0x666 && *f <= 0x669) + { + d = (*f) - 0x666; + k = file[d].pos; + } + else + k = lseek(*f, 0, 1); + + return (long) k; +} + +static int mem_open(char * ogg, int size) +{ + static int one = 1; + int n; + if (one) + { + one = 0; + for (n = 0; n < 4; n++) + file[n].size = 0; + } + + for (n = 0; n < 4; n++) + { + if (file[n].size == 0) + { + file[n].mem = ogg; + file[n].size = size; + file[n].pos = 0; + return (0x666 + n); + } + } + return -1; +} + +static int mem_close(int fd) +{ + if (fd >= 0x666 && fd <= 0x669) // it is a memory file descriptor? + { + fd -= 0x666; + file[fd].size = 0; + return 0; + } + else + return f_close(&fd); +} + +static ov_callbacks callbacks = { + (size_t (*)(void *, size_t, size_t, void *)) f_read, + (int (*)(void *, ogg_int64_t, int)) f_seek, + (int (*)(void *)) f_close, + (long (*)(void *)) f_tell +}; + +/* OGG control */ + +#define READ_SAMPLES 4096 /* samples that it must read before to send */ +#define MAX_PCMOUT 4096 /* minimum size to read ogg samples */ +typedef struct +{ + OggVorbis_File vf; + vorbis_info *vi; + int current_section; + + /* OGG file operation */ + int fd; + int mode; + int eof; + int flag; + int volume; + int seek_time; + + /* OGG buffer control */ + short pcmout[2][READ_SAMPLES + MAX_PCMOUT * 2]; /* take 4k out of the data segment, not the stack */ + int pcmout_pos; + int pcm_indx; + +} private_data_ogg; + +static private_data_ogg private_ogg; + +/* OGG thread control */ + +#define STACKSIZE 8192 + +static u8 oggplayer_stack[STACKSIZE]; +static lwpq_t oggplayer_queue = LWP_TQUEUE_NULL; +static lwp_t h_oggplayer = LWP_THREAD_NULL; +static int ogg_thread_running = 0; + +static void ogg_add_callback(int voice) +{ + if (!ogg_thread_running) + { + ASND_StopVoice(0); + return; + } + + if (private_ogg.flag & 128) + return; /* Ogg is paused */ + + if (private_ogg.pcm_indx >= READ_SAMPLES) + { + if (ASND_AddVoice(0, + (void *) private_ogg.pcmout[private_ogg.pcmout_pos], + private_ogg.pcm_indx << 1) == 0) + { + private_ogg.pcmout_pos ^= 1; + private_ogg.pcm_indx = 0; + private_ogg.flag = 0; + LWP_ThreadSignal(oggplayer_queue); + } + } + else + { + if (private_ogg.flag & 64) + { + private_ogg.flag &= ~64; + LWP_ThreadSignal(oggplayer_queue); + } + } +} + +static void * ogg_player_thread(private_data_ogg * priv) +{ + int first_time = 1; + long ret; + + /* init */ + LWP_InitQueue(&oggplayer_queue); + + priv[0].vi = ov_info(&priv[0].vf, -1); + + ASND_Pause(0); + + priv[0].pcm_indx = 0; + priv[0].pcmout_pos = 0; + priv[0].eof = 0; + priv[0].flag = 0; + priv[0].current_section = 0; + + ogg_thread_running = 1; + + while (!priv[0].eof && ogg_thread_running) + { + if (priv[0].flag) + LWP_ThreadSleep(oggplayer_queue); /* wait only when i have samples to send */ + + if (priv[0].flag == 0) /* wait to all samples are sended */ + { + if (ASND_TestPointer(0, priv[0].pcmout[priv[0].pcmout_pos]) + && ASND_StatusVoice(0) != SND_UNUSED) + { + priv[0].flag |= 64; + continue; + } + if (priv[0].pcm_indx < READ_SAMPLES) + { + priv[0].flag = 3; + + if (priv[0].seek_time >= 0) + { + ov_time_seek(&priv[0].vf, priv[0].seek_time); + priv[0].seek_time = -1; + } + + ret + = ov_read( + &priv[0].vf, + (void *) &priv[0].pcmout[priv[0].pcmout_pos][priv[0].pcm_indx], + MAX_PCMOUT,/*0,2,1,*/&priv[0].current_section); + priv[0].flag &= 192; + if (ret == 0) + { + /* EOF */ + if (priv[0].mode & 1) + ov_time_seek(&priv[0].vf, 0); /* repeat */ + else + priv[0].eof = 1; /* stops */ + } + else if (ret < 0) + { + /* error in the stream. Not a problem, just reporting it in + case we (the app) cares. In this case, we don't. */ + if (ret != OV_HOLE) + { + if (priv[0].mode & 1) + ov_time_seek(&priv[0].vf, 0); /* repeat */ + else + priv[0].eof = 1; /* stops */ + } + } + else + { + /* we don't bother dealing with sample rate changes, etc, but + you'll have to */ + priv[0].pcm_indx += ret >> 1; /* get 16 bits samples */ + } + } + else + priv[0].flag = 1; + } + + if (priv[0].flag == 1) + { + if (ASND_StatusVoice(0) == SND_UNUSED || first_time) + { + first_time = 0; + if (priv[0].vi->channels == 2) + { + ASND_SetVoice(0, VOICE_STEREO_16BIT, priv[0].vi->rate, 0, + (void *) priv[0].pcmout[priv[0].pcmout_pos], + priv[0].pcm_indx << 1, priv[0].volume, + priv[0].volume, ogg_add_callback); + priv[0].pcmout_pos ^= 1; + priv[0].pcm_indx = 0; + priv[0].flag = 0; + } + else + { + ASND_SetVoice(0, VOICE_MONO_16BIT, priv[0].vi->rate, 0, + (void *) priv[0].pcmout[priv[0].pcmout_pos], + priv[0].pcm_indx << 1, priv[0].volume, + priv[0].volume, ogg_add_callback); + priv[0].pcmout_pos ^= 1; + priv[0].pcm_indx = 0; + priv[0].flag = 0; + } + } + } + usleep(10); + } + ov_clear(&priv[0].vf); + priv[0].fd = -1; + priv[0].pcm_indx = 0; + + return 0; +} + +void StopOgg() +{ + ASND_StopVoice(0); + ogg_thread_running = 0; + + if(h_oggplayer != LWP_THREAD_NULL) + { + if(oggplayer_queue != LWP_TQUEUE_NULL) + LWP_ThreadSignal(oggplayer_queue); + LWP_JoinThread(h_oggplayer, NULL); + h_oggplayer = LWP_THREAD_NULL; + } + if(oggplayer_queue != LWP_TQUEUE_NULL) + { + LWP_CloseQueue(oggplayer_queue); + oggplayer_queue = LWP_TQUEUE_NULL; + } +} + +int PlayOgg(char * buf, int buflen, int time_pos, int mode) +{ + StopOgg(); + + private_ogg.fd = mem_open(buf, buflen); + + if (private_ogg.fd < 0) + { + private_ogg.fd = -1; + return -1; + } + + private_ogg.mode = mode; + private_ogg.eof = 0; + private_ogg.volume = 127; + private_ogg.flag = 0; + private_ogg.seek_time = -1; + + if (time_pos > 0) + private_ogg.seek_time = time_pos; + + if (ov_open_callbacks((void *) &private_ogg.fd, &private_ogg.vf, NULL, 0, callbacks) < 0) + { + mem_close(private_ogg.fd); /* mem_close() can too close files from devices */ + private_ogg.fd = -1; + ogg_thread_running = 0; + return -1; + } + + if (LWP_CreateThread(&h_oggplayer, (void *) ogg_player_thread, + &private_ogg, oggplayer_stack, STACKSIZE, 80) == -1) + { + ogg_thread_running = 0; + ov_clear(&private_ogg.vf); + private_ogg.fd = -1; + return -1; + } + return 0; +} + +void PauseOgg(int pause) +{ + if (pause) + { + private_ogg.flag |= 128; + } + else + { + if (private_ogg.flag & 128) + { + private_ogg.flag |= 64; + private_ogg.flag &= ~128; + if (ogg_thread_running > 0) + { + LWP_ThreadSignal(oggplayer_queue); + } + } + } +} + +int StatusOgg() +{ + if (ogg_thread_running == 0) + return -1; /* Error */ + else if (private_ogg.eof) + return 255; /* EOF */ + else if (private_ogg.flag & 128) + return 2; /* paused */ + else + return 1; /* running */ +} + +void SetVolumeOgg(int volume) +{ + private_ogg.volume = volume; + ASND_ChangeVolumeVoice(0, volume, volume); +} + +s32 GetTimeOgg() +{ + int ret; + if (ogg_thread_running == 0 || private_ogg.fd < 0) + return 0; + ret = ((s32) ov_time_tell(&private_ogg.vf)); + if (ret < 0) + ret = 0; + + return ret; +} + +void SetTimeOgg(s32 time_pos) +{ + if (time_pos >= 0) + private_ogg.seek_time = time_pos; +} + diff --git a/genplus-gx/gx/utils/oggplayer.h b/genplus-gx/gx/utils/oggplayer.h new file mode 100644 index 0000000000..85b95c6a88 --- /dev/null +++ b/genplus-gx/gx/utils/oggplayer.h @@ -0,0 +1,179 @@ +/* + Copyright (c) 2008 Francisco Muñoz 'Hermes' + All rights reserved. + + Proper (standard) vorbis usage by Tantric, 2009 + Threading modifications/corrections by Tantric, 2009 + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + - The names of the contributors may not be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NO_SOUND + +#ifndef __OGGPLAYER_H__ +#define __OGGPLAYER_H__ + +#include +#include "tremor/ivorbiscodec.h" +#include "tremor/ivorbisfile.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define OGG_ONE_TIME 0 +#define OGG_INFINITE_TIME 1 + +#define OGG_STATUS_RUNNING 1 +#define OGG_STATUS_ERR -1 +#define OGG_STATUS_PAUSED 2 +#define OGG_STATUS_EOF 255 + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Player OGG functions */ +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* int PlayOgg(int fd, int time_pos, int mode); + + Play an Ogg file. This file can be loaded from memory (mem_open(void *ogg, int size_ogg)) or from device with open("device:file.ogg",O_RDONLY,0); + + NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail. + + -- Params --- + + buf: pointer to sound data + + buflen: buffer size in bytes + + time_pos: initial time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds + + mode: Use OGG_ONE_TIME or OGG_INFINITE_TIME. When you use OGG_ONE_TIME the sound stops and StatusOgg() return OGG_STATUS_EOF + + return: 0- Ok, -1 Error + + */ + +int PlayOgg(char * buf, int buflen, int time_pos, int mode); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* void StopOgg(); + + Stop an Ogg file. + + NOTE: The file is closed and the player thread is released + + -- Params --- + + + */ + +void StopOgg(); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* void PauseOgg(int pause); + + Pause an Ogg file. + + -- Params --- + + pause: 0 -> continue, 1-> pause + + */ + +void PauseOgg(int pause); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* int StatusOgg(); + + Return the Ogg status + + -- Params --- + + + return: OGG_STATUS_RUNNING + OGG_STATUS_ERR -> not initialized? + OGG_STATUS_PAUSED + OGG_STATUS_EOF -> player stopped by End Of File + + */ + +int StatusOgg(); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* void SetVolumeOgg(int volume); + + Set the Ogg playing volume. + NOTE: it change the volume of voice 0 (used for the Ogg player) + + -- Params --- + + volume: 0 to 255 (max) + + */ + +void SetVolumeOgg(int volume); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* s32 GetTimeOgg(); + + Return the Ogg time from the starts of the file + + -- Params --- + + return: 0 -> Ok or error condition (you must ignore this value) + >0 -> time in milliseconds from the starts + + */ + +s32 GetTimeOgg(); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* void SetTimeOgg(s32 time_pos); + + Set the time position + + NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail. + + -- Params --- + + time_pos: time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds + + */ + +void SetTimeOgg(s32 time_pos); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/genplus-gx/gx/utils/vi_encoder.c b/genplus-gx/gx/utils/vi_encoder.c new file mode 100644 index 0000000000..402fa79199 --- /dev/null +++ b/genplus-gx/gx/utils/vi_encoder.c @@ -0,0 +1,565 @@ +/**************************************************************************** + * vi_encoder.c + * + * Wii Audio/Video Encoder support + * + * Copyright (C) 2009 Eke-Eke, with some code from libogc (C) Hector Martin + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifdef HW_RVL + +#include +#include +#include +#include + +#include "vi_encoder.h" + +/**************************************************************************** + * I2C driver by Hector Martin (marcan) + * + ****************************************************************************/ + +#define _SHIFTL(v, s, w) \ + ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s))) +#define _SHIFTR(v, s, w) \ + ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1))) + +extern void udelay(int us); + +static u32 i2cIdentFirst = 0; +static u32 i2cIdentFlag = 1; +static vu16* const _viReg = (u16*)0xCC002000; +static vu32* const _i2cReg = (u32*)0xCD800000; + +static inline void __viOpenI2C(u32 channel) +{ + u32 val = ((_i2cReg[49]&~0x8000)|0x4000); + val |= _SHIFTL(channel,15,1); + _i2cReg[49] = val; +} + +static inline u32 __viSetSCL(u32 channel) +{ + u32 val = (_i2cReg[48]&~0x4000); + val |= _SHIFTL(channel,14,1); + _i2cReg[48] = val; + return 1; +} +static inline u32 __viSetSDA(u32 channel) +{ + u32 val = (_i2cReg[48]&~0x8000); + val |= _SHIFTL(channel,15,1); + _i2cReg[48] = val; + return 1; +} + +static inline u32 __viGetSDA() +{ + return _SHIFTR(_i2cReg[50],15,1); +} + +static inline void __viCheckI2C() +{ + __viOpenI2C(0); + udelay(4); + + i2cIdentFlag = 0; + if(__viGetSDA()!=0) i2cIdentFlag = 1; +} + +static u32 __sendSlaveAddress(u8 addr) +{ + u32 i; + + __viSetSDA(i2cIdentFlag^1); + udelay(2); + + __viSetSCL(0); + for(i=0;i<8;i++) { + if(addr&0x80) __viSetSDA(i2cIdentFlag); + else __viSetSDA(i2cIdentFlag^1); + udelay(2); + + __viSetSCL(1); + udelay(2); + + __viSetSCL(0); + addr <<= 1; + } + + __viOpenI2C(0); + udelay(2); + + __viSetSCL(1); + udelay(2); + + if(i2cIdentFlag==1 && __viGetSDA()!=0) return 0; + + __viSetSDA(i2cIdentFlag^1); + __viOpenI2C(1); + __viSetSCL(0); + + return 1; +} + +static u32 __VISendI2CData(u8 addr,void *val,u32 len) +{ + u8 c; + s32 i,j; + u32 level,ret; + + if(i2cIdentFirst==0) { + __viCheckI2C(); + i2cIdentFirst = 1; + } + + _CPU_ISR_Disable(level); + + __viOpenI2C(1); + __viSetSCL(1); + + __viSetSDA(i2cIdentFlag); + udelay(4); + + ret = __sendSlaveAddress(addr); + if(ret==0) { + _CPU_ISR_Restore(level); + return 0; + } + + __viOpenI2C(1); + for(i=0;i> 8; + buf[2] = data & 0xFF; + __VISendI2CData(0xe0,buf,3); + udelay(2); +} + +static void __VIWriteI2CRegister32(u8 reg, u32 data) +{ + u8 buf[5]; + buf[0] = reg; + buf[1] = data >> 24; + buf[2] = (data >> 16) & 0xFF; + buf[3] = (data >> 8) & 0xFF; + buf[4] = data & 0xFF; + __VISendI2CData(0xe0,buf,5); + udelay(2); +} + +static void __VIWriteI2CRegisterBuf(u8 reg, int size, u8 *data) +{ + u8 buf[0x100]; + buf[0] = reg; + memcpy(&buf[1], data, size); + __VISendI2CData(0xe0,buf,size+1); + udelay(2); +} + +/**************************************************************************** + * A/V functions support (Eke-Eke) + * + ****************************************************************************/ +static const u8 gamma_coeffs[][33] = +{ + /* GM_0_0 */ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + }, + + /* GM_0_1 */ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x97, 0x3B, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x80, 0x1B, 0x80, 0xEB, 0x00 + }, + + /* GM_0_2 */ + { + 0x00, 0x00, 0x00, 0x28, 0x00, 0x5A, 0x02, 0xDB, 0x0D, 0x8D, 0x30, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0x00, 0x10, 0x40, 0x11, 0x00, 0x18, 0x80, 0x42, 0x00, 0xEB, 0x00 + }, + + /* GM_0_3 */ + { + 0x00, 0x00, 0x00, 0x7A, 0x02, 0x3C, 0x07, 0x6D, 0x12, 0x9C, 0x27, 0x24, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0x00, 0x10, 0xC0, 0x15, 0x80, 0x29, 0x00, 0x62, 0x00, 0xEB, 0x00 + }, + + /* GM_0_4 */ + { + 0x00, 0x4E, 0x01, 0x99, 0x05, 0x2D, 0x0B, 0x24, 0x14, 0x29, 0x20, 0xA4, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x00, 0x10, 0x10, 0x40, 0x12, 0xC0, 0x1D, 0xC0, 0x3B, 0x00, 0x78, 0xC0, 0xEB, 0x00 + }, + + /* GM_0_5 */ + { + 0x00, 0xEC, 0x03, 0xD7, 0x08, 0x00, 0x0D, 0x9E, 0x14, 0x3E, 0x1B, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x10, 0xC0, 0x16, 0xC0, 0x27, 0xC0, 0x4B, 0x80, 0x89, 0x80, 0xEB, 0x00 + }, + + /* GM_0_6 */ + { + 0x02, 0x76, 0x06, 0x66, 0x0A, 0x96, 0x0E, 0xF3, 0x13, 0xAC, 0x18, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x12, 0x00, 0x1C, 0x00, 0x32, 0x80, 0x59, 0xC0, 0x96, 0x00, 0xEB, 0x00 + }, + + /* GM_0_7 */ + { + 0x04, 0xEC, 0x08, 0xF5, 0x0C, 0x96, 0x0F, 0xCF, 0x12, 0xC6, 0x15, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x14, 0x00, 0x22, 0x00, 0x3C, 0xC0, 0x66, 0x40, 0x9F, 0xC0, 0xEB, 0x00 + }, + + /* GM_0_8 */ + { + 0x08, 0x00, 0x0B, 0xAE, 0x0E, 0x00, 0x10, 0x30, 0x11, 0xCB, 0x13, 0x49, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x16, 0x80, 0x28, 0xC0, 0x46, 0x80, 0x71, 0x00, 0xA7, 0x80, 0xEB, 0x00 + }, + + /* GM_0_9 */ + { + 0x0B, 0xB1, 0x0E, 0x14, 0x0F, 0x2D, 0x10, 0x18, 0x10, 0xE5, 0x11, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x19, 0x80, 0x2F, 0x80, 0x4F, 0xC0, 0x7A, 0x00, 0xAD, 0xC0, 0xEB, 0x00 + }, + + /* GM_1_0 */ + { + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, + 0x10, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xEB, + 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x00, 0x80, 0x00, 0xA0, 0x00, 0xEB, 0x00 + }, + + /* GM_1_1 */ + { + 0x14, 0xEC, 0x11, 0xC2, 0x10, 0x78, 0x0F, 0xB6, 0x0F, 0x2F, 0x0E, 0xB6, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x21, 0x00, 0x3C, 0xC0, 0x5F, 0xC0, 0x89, 0x00, 0xB7, 0x80, 0xEB, 0x00 + }, + + /* GM_1_2 */ + { + 0x19, 0xD8, 0x13, 0x33, 0x10, 0xD2, 0x0F, 0x6D, 0x0E, 0x5E, 0x0D, 0xA4, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x25, 0x00, 0x43, 0x00, 0x66, 0xC0, 0x8F, 0x40, 0xBB, 0x40, 0xEB, 0x00 + }, + + /* GM_1_3 */ + { + 0x1E, 0xC4, 0x14, 0x7A, 0x11, 0x0F, 0xF, 0x0C, 0x0D, 0xA1, 0x0C, 0xB6, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x29, 0x00, 0x49, 0x00, 0x6D, 0x40, 0x94, 0xC0, 0xBE, 0x80, 0xEB, 0x00 + }, + + /* GM_1_4 */ + { + 0x24, 0x00, 0x15, 0x70, 0x11, 0x0F, 0x0E, 0xAA, 0x0D, 0x0F, 0x0B, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x2D, 0x40, 0x4E, 0xC0, 0x73, 0x00, 0x99, 0x80, 0xC1, 0x80, 0xEB, 0x00 + }, + + /* GM_1_5 */ + { + 0x29, 0x3B, 0x16, 0x3D, 0x11, 0x0F, 0x0E, 0x30, 0x0C, 0x7D, 0x0B, 0x24, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x31, 0x80, 0x54, 0x40, 0x78, 0x80, 0x9D, 0xC0, 0xC4, 0x00, 0xEB, 0x00 + }, + + /* GM_1_6 */ + { + 0x2E, 0x27, 0x17, 0x0A, 0x10, 0xD2, 0x0D, 0xE7, 0x0B, 0xEB, 0x0A, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x35, 0x80, 0x59, 0x80, 0x7D, 0x40, 0xA1, 0xC0, 0xC6, 0x40, 0xEB, 0x00 + }, + + /* GM_1_7 */ + { + 0x33, 0x62, 0x17, 0x5C, 0x10, 0xD2, 0x0D, 0x6D, 0x0B, 0x6D, 0x09, 0xED, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x39, 0xC0, 0x5E, 0x40, 0x82, 0x00, 0xA5, 0x40, 0xC8, 0x40, 0xEB, 0x00 + }, + + /* GM_1_8 */ + { + 0x38, 0x4E, 0x17, 0xAE, 0x10, 0xB4, 0x0D, 0x0C, 0x0A, 0xF0, 0x09, 0x6D, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x3D, 0xC0, 0x62, 0xC0, 0x86, 0x40, 0xA8, 0x80, 0xCA, 0x00, 0xEB, 0x00 + }, + + /* GM_1_9 */ + { + 0x3D, 0x3B, 0x18, 0x00, 0x10, 0x5A, 0x0C, 0xC3, 0x0A, 0x72, 0x09, 0x00, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x41, 0xC0, 0x67, 0x40, 0x8A, 0x00, 0xAB, 0x80, 0xCB, 0x80, 0xEB, 0x00 + }, + + /* GM_2_0 */ + { + 0x41, 0xD8, 0x18, 0x28, 0x10, 0x3C, 0x0C, 0x49, 0x0A, 0x1F, 0x08, 0x92, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x45, 0x80, 0x6B, 0x40, 0x8D, 0xC0, 0xAE, 0x00, 0xCD, 0x00, 0xEB, 0x00 + }, + + /* GM_2_1 */ + { + 0x46, 0x76, 0x18, 0x51, 0x0F, 0xE1, 0x0C, 0x00, 0x09, 0xB6, 0x08, 0x36, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x49, 0x40, 0x6F, 0x40, 0x91, 0x00, 0xB0, 0x80, 0xCE, 0x40, 0xEB, 0x00 + }, + + /* GM_2_2 */ + { + 0x4A, 0xC4, 0x18, 0x7A, 0x0F, 0xA5, 0x0B, 0x9E, 0x09, 0x63, 0x07, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x4C, 0xC0, 0x73, 0x00, 0x94, 0x40, 0xB2, 0xC0, 0xCF, 0x80, 0xEB, 0x00 + }, + + /* GM_2_3 */ + { + 0x4F, 0x13, 0x18, 0x51, 0x0F, 0x69, 0x0B, 0x6D, 0x09, 0x0F, 0x07, 0x80, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x50, 0x40, 0x76, 0x40, 0x97, 0x00, 0xB5, 0x00, 0xD0, 0xC0, 0xEB, 0x00 + }, + + /* GM_2_4 */ + { + 0x53, 0x13, 0x18, 0x7A, 0x0F, 0x0F, 0x0B, 0x24, 0x08, 0xBC, 0x07, 0x36, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x53, 0x80, 0x79, 0xC0, 0x99, 0xC0, 0xB7, 0x00, 0xD1, 0xC0, 0xEB, 0x00 + }, + + /* GM_2_5 */ + { + 0x57, 0x13, 0x18, 0x51, 0x0E, 0xF0, 0x0A, 0xC3, 0x08, 0x7D, 0x06, 0xED, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x56, 0xC0, 0x7C, 0xC0, 0x9C, 0x80, 0xB8, 0xC0, 0xD2, 0xC0, 0xEB, 0x00 + }, + + /* GM_2_6 */ + { + 0x5B, 0x13, 0x18, 0x28, 0x0E, 0x96, 0x0A, 0x92, 0x08, 0x29, 0x06, 0xB6, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x5A, 0x00, 0x7F, 0xC0, 0x9E, 0xC0, 0xBA, 0x80, 0xD3, 0x80, 0xEB, 0x00 + }, + + /* GM_2_7 */ + { + 0x5E, 0xC4, 0x18, 0x00, 0x0E, 0x78, 0x0A, 0x30, 0x08, 0x00, 0x06, 0x6D, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x5D, 0x00, 0x82, 0x80, 0xA1, 0x40, 0xBC, 0x00, 0xD4, 0x80, 0xEB, 0x00 + }, + + /* GM_2_8 */ + { + 0x62, 0x76, 0x17, 0xD7, 0x0E, 0x1E, 0x0A, 0x00, 0x07, 0xC1, 0x06, 0x36, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x60, 0x00, 0x85, 0x40, 0xA3, 0x40, 0xBD, 0x80, 0xD5, 0x40, 0xEB, 0x00 + }, + + /* GM_2_9 */ + { + 0x65, 0xD8, 0x17, 0xAE, 0x0D, 0xE1, 0x09, 0xCF, 0x07, 0x82, 0x06, 0x00, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x62, 0xC0, 0x87, 0xC0, 0xA5, 0x40, 0xBF, 0x00, 0xD6, 0x00, 0xEB, 0x00 + }, + + /* GM_3_0 */ + { + 0x69, 0x3B, 0x17, 0x85, 0x0D, 0xA5, 0x09, 0x86, 0x07, 0x43, 0x05, 0xDB, + 0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB, + 0x10, 0x00, 0x65, 0x80, 0x8A, 0x40, 0xA7, 0x40, 0xC0, 0x40, 0xD6, 0x80, 0xEB, 0x00 + } +}; + +void __VISetTiming(u8 timing) +{ + __VIWriteI2CRegister8(0x00,timing); +} + +void __VISetYUVSEL(u8 dtvstatus) +{ + u8 vdacFlagRegion = 0; + u32 currTvMode = _SHIFTR(_viReg[1],8,2); + if(currTvMode==VI_PAL || currTvMode==VI_EURGB60) + vdacFlagRegion = 2; + else if(currTvMode==VI_MPAL) + vdacFlagRegion = 1; + + __VIWriteI2CRegister8(0x01, _SHIFTL(dtvstatus,5,3)|(vdacFlagRegion&0x1f)); +} + +void __VISetVBICtrl(u16 data) +{ + __VIWriteI2CRegister16(0x02, data); +} + +void __VISetTrapFilter(u8 disable) +{ + if (disable) + __VIWriteI2CRegister8(0x03, 0); + else + __VIWriteI2CRegister8(0x03, 1); +} + +void __VISet3in1Output(u8 enable) +{ + __VIWriteI2CRegister8(0x04,enable); +} + +void __VISetCGMS(u16 value) +{ + __VIWriteI2CRegister16(0x05, value); +} + +void __VISetWSS(u16 value) +{ + __VIWriteI2CRegister16(0x08, value); +} + +void __VISetRGBOverDrive(u8 value) +{ + u32 currTvMode = _SHIFTR(_viReg[1],8,2); + if (currTvMode == VI_DEBUG) + __VIWriteI2CRegister8(0x0A,(value<<1)|1); + else + __VIWriteI2CRegister8(0x0A,0); +} + +void __VISetOverSampling(void) +{ + __VIWriteI2CRegister8(0x65,1); +} + +void __VISetCCSEL(void) +{ + __VIWriteI2CRegister8(0x6a,1); +} + +void __VISetFilterEURGB60(u8 enable) +{ + __VIWriteI2CRegister8(0x6e, enable); +} + +void __VISetVolume(u16 value) +{ + __VIWriteI2CRegister16(0x71,value); +} + +void __VISetClosedCaption(u32 value) +{ + __VIWriteI2CRegister32(0x7a, value); +} + +void __VISetGamma(VIGamma gamma) +{ + u8 *data = (u8 *)&gamma_coeffs[gamma][0]; + __VIWriteI2CRegisterBuf(0x10, 0x21, data); +} + +/* User Configurable */ + +void VIDEO_SetGamma(VIGamma gamma) +{ + __VISetGamma(gamma); +} + +void VIDEO_SetTrapFilter(bool enable) +{ + if (enable) + __VISetTrapFilter(0); + else + __VISetTrapFilter(1); +} + +#endif diff --git a/genplus-gx/gx/utils/vi_encoder.h b/genplus-gx/gx/utils/vi_encoder.h new file mode 100644 index 0000000000..f5290dc568 --- /dev/null +++ b/genplus-gx/gx/utils/vi_encoder.h @@ -0,0 +1,79 @@ +/**************************************************************************** + * vi_encoder.c + * + * Wii Audio/Video Encoder support + * + * Copyright (C) 2009 Eke-Eke, with some code from libogc (C) Hector Martin + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ +#ifdef HW_RVL + +typedef enum +{ + VI_GM_0_1=1, + VI_GM_0_2, + VI_GM_0_3, + VI_GM_0_4, + VI_GM_0_5, + VI_GM_0_6, + VI_GM_0_7, + VI_GM_0_8, + VI_GM_0_9, + VI_GM_1_0, + VI_GM_1_1, + VI_GM_1_2, + VI_GM_1_3, + VI_GM_1_4, + VI_GM_1_5, + VI_GM_1_6, + VI_GM_1_7, + VI_GM_1_8, + VI_GM_1_9, + VI_GM_2_0, + VI_GM_2_1, + VI_GM_2_2, + VI_GM_2_3, + VI_GM_2_4, + VI_GM_2_5, + VI_GM_2_6, + VI_GM_2_7, + VI_GM_2_8, + VI_GM_2_9, + VI_GM_3_0 +} VIGamma; + +extern void VIDEO_SetGamma(VIGamma gamma); +extern void VIDEO_SetTrapFilter(bool enable); + + +#endif diff --git a/genplus-gx/libretro/jni/Android.mk b/genplus-gx/libretro/jni/Android.mk new file mode 100644 index 0000000000..4546bfa73c --- /dev/null +++ b/genplus-gx/libretro/jni/Android.mk @@ -0,0 +1,78 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +GENPLUS_SRC_DIR := ../../core +LIBRETRO_DIR := ../ + +LOCAL_MODULE := retro + +ifeq ($(TARGET_ARCH),arm) +LOCAL_CFLAGS += -DANDROID_ARM +LOCAL_ARM_MODE := arm +endif + +LOCAL_SRC_FILES := $(GENPLUS_SRC_DIR)/genesis.c \ + $(GENPLUS_SRC_DIR)/vdp_ctrl.c \ + $(GENPLUS_SRC_DIR)/vdp_render.c \ + $(GENPLUS_SRC_DIR)/system.c \ + $(GENPLUS_SRC_DIR)/io_ctrl.c \ + $(GENPLUS_SRC_DIR)/loadrom.c \ + $(GENPLUS_SRC_DIR)/mem68k.c \ + $(GENPLUS_SRC_DIR)/state.c \ + $(GENPLUS_SRC_DIR)/memz80.c \ + $(GENPLUS_SRC_DIR)/membnk.c \ + $(GENPLUS_SRC_DIR)/input_hw/activator.c \ + $(GENPLUS_SRC_DIR)/input_hw/gamepad.c \ + $(GENPLUS_SRC_DIR)/input_hw/input.c \ + $(GENPLUS_SRC_DIR)/input_hw/lightgun.c \ + $(GENPLUS_SRC_DIR)/input_hw/mouse.c \ + $(GENPLUS_SRC_DIR)/input_hw/paddle.c \ + $(GENPLUS_SRC_DIR)/input_hw/sportspad.c \ + $(GENPLUS_SRC_DIR)/input_hw/teamplayer.c \ + $(GENPLUS_SRC_DIR)/input_hw/xe_a1p.c \ + $(GENPLUS_SRC_DIR)/input_hw/terebi_oekaki.c \ + $(GENPLUS_SRC_DIR)/cd_hw/cd_cart.c \ + $(GENPLUS_SRC_DIR)/cd_hw/cdc.c \ + $(GENPLUS_SRC_DIR)/cd_hw/cdd.c \ + $(GENPLUS_SRC_DIR)/cd_hw/gfx.c \ + $(GENPLUS_SRC_DIR)/cd_hw/pcm.c \ + $(GENPLUS_SRC_DIR)/cd_hw/scd.c \ + $(GENPLUS_SRC_DIR)/cart_hw/areplay.c \ + $(GENPLUS_SRC_DIR)/cart_hw/md_cart.c \ + $(GENPLUS_SRC_DIR)/cart_hw/sms_cart.c \ + $(GENPLUS_SRC_DIR)/cart_hw/eeprom_93c.c \ + $(GENPLUS_SRC_DIR)/cart_hw/eeprom_i2c.c \ + $(GENPLUS_SRC_DIR)/cart_hw/eeprom_spi.c \ + $(GENPLUS_SRC_DIR)/cart_hw/ggenie.c \ + $(GENPLUS_SRC_DIR)/cart_hw/sram.c \ + $(GENPLUS_SRC_DIR)/cart_hw/svp/ssp16.c \ + $(GENPLUS_SRC_DIR)/cart_hw/svp/svp.c \ + $(GENPLUS_SRC_DIR)/ntsc/md_ntsc.c \ + $(GENPLUS_SRC_DIR)/ntsc/sms_ntsc.c \ + $(GENPLUS_SRC_DIR)/sound/eq.c \ + $(GENPLUS_SRC_DIR)/sound/sound.c \ + $(GENPLUS_SRC_DIR)/sound/ym2612.c \ + $(GENPLUS_SRC_DIR)/sound/ym2413.c \ + $(GENPLUS_SRC_DIR)/sound/sn76489.c \ + $(GENPLUS_SRC_DIR)/sound/blip_buf.c \ + $(GENPLUS_SRC_DIR)/z80/z80.c \ + $(GENPLUS_SRC_DIR)/m68k/m68kcpu.c \ + $(GENPLUS_SRC_DIR)/m68k/s68kcpu.c \ + $(LIBRETRO_DIR)/libretro.c \ + $(LIBRETRO_DIR)/scrc32.c + +LOCAL_C_INCLUDES = $(LOCAL_PATH)/$(GENPLUS_SRC_DIR) \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/sound \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/input_hw \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/cd_hw \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/cart_hw \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/cart_hw/svp \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/m68k \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/z80 \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/ntsc \ + $(LOCAL_PATH)/$(LIBRETRO_DIR) + +LOCAL_CFLAGS = -ffast-math -O3 -funroll-loops -DINLINE="static inline" -DUSE_16BPP_RENDERING -DLSB_FIRST -D__LIBRETRO__ -DFRONTEND_SUPPORTS_RGB565 -DALIGN_LONG -DALIGN_WORD + +include $(BUILD_SHARED_LIBRARY) diff --git a/genplus-gx/libretro/jni/Application.mk b/genplus-gx/libretro/jni/Application.mk new file mode 100644 index 0000000000..9dcdc3c570 --- /dev/null +++ b/genplus-gx/libretro/jni/Application.mk @@ -0,0 +1 @@ +APP_ABI := all diff --git a/genplus-gx/libretro/libretro.c b/genplus-gx/libretro/libretro.c new file mode 100644 index 0000000000..67fdda7d16 --- /dev/null +++ b/genplus-gx/libretro/libretro.c @@ -0,0 +1,1005 @@ +#ifndef _MSC_VER +#include +#endif +#include +#include +#include + +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + +#ifdef _XBOX1 +#include +#endif + +#include "shared.h" +#include "libretro.h" +#include "state.h" +#include "genesis.h" +#include "md_ntsc.h" +#include "sms_ntsc.h" + +sms_ntsc_t *sms_ntsc; +md_ntsc_t *md_ntsc; + +char GG_ROM[256]; +char AR_ROM[256]; +char SK_ROM[256]; +char SK_UPMEM[256]; +char GG_BIOS[256]; +char MS_BIOS_EU[256]; +char MS_BIOS_JP[256]; +char MS_BIOS_US[256]; +char CD_BIOS_EU[256]; +char CD_BIOS_US[256]; +char CD_BIOS_JP[256]; +char CD_BRAM_JP[256]; +char CD_BRAM_US[256]; +char CD_BRAM_EU[256]; +char CART_BRAM[256]; + +static int vwidth; +static int vheight; + +static uint32_t brm_crc[2]; +static uint8_t brm_format[0x40] = +{ + 0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x00,0x00,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x53,0x45,0x47,0x41,0x5f,0x43,0x44,0x5f,0x52,0x4f,0x4d,0x00,0x01,0x00,0x00,0x00, + 0x52,0x41,0x4d,0x5f,0x43,0x41,0x52,0x54,0x52,0x49,0x44,0x47,0x45,0x5f,0x5f,0x5f +}; + +static uint8_t temp[0x10000]; +static int16 soundbuffer[3068]; +static uint16_t bitmap_data_[1024 * 512]; +static const double pal_fps = 53203424.0 / (3420.0 * 313.0); +static const double ntsc_fps = 53693175.0 / (3420.0 * 262.0); + +static char g_rom_dir[1024]; + +static retro_video_refresh_t video_cb; +static retro_input_poll_t input_poll_cb; +static retro_input_state_t input_state_cb; +static retro_environment_t environ_cb; +static retro_audio_sample_batch_t audio_cb; + +/************************************ + * Genesis Plus GX implementation + ************************************/ +#define CHUNKSIZE (0x10000) + +void error(char * msg, ...) +{ +#ifndef _XBOX1 + va_list ap; + va_start(ap, msg); + vfprintf(stderr, msg, ap); + va_end(ap); +#endif +} + +int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension) +{ + int size, left; + + /* Open file */ + FILE *fd = fopen(filename, "rb"); + + if (!fd) + { + /* Master System & Game Gear BIOS are optional files */ + if (!strcmp(filename,MS_BIOS_US) || !strcmp(filename,MS_BIOS_EU) || !strcmp(filename,MS_BIOS_JP) || !strcmp(filename,GG_BIOS)) + { + return 0; + } + + /* Mega CD BIOS are required files */ + if (!strcmp(filename,CD_BIOS_US) || !strcmp(filename,CD_BIOS_EU) || !strcmp(filename,CD_BIOS_JP)) + { + fprintf(stderr, "ERROR - Unable to open CD BIOS: %s.\n", filename); + return 0; + } + + fprintf(stderr, "ERROR - Unable to open file.\n"); + return 0; + } + + /* Get file size */ + fseek(fd, 0, SEEK_END); + size = ftell(fd); + + /* size limit */ + if(size > maxsize) + { + fclose(fd); + fprintf(stderr, "ERROR - File is too large.\n"); + return 0; + } + + fprintf(stderr, "INFORMATION - Loading %d bytes ...\n", size); + + /* filename extension */ + if (extension) + { + memcpy(extension, &filename[strlen(filename) - 3], 3); + extension[3] = 0; + } + + /* Read into buffer */ + left = size; + fseek(fd, 0, SEEK_SET); + while (left > CHUNKSIZE) + { + fread(buffer, CHUNKSIZE, 1, fd); + buffer += CHUNKSIZE; + left -= CHUNKSIZE; + } + + /* Read remaining bytes */ + fread(buffer, left, 1, fd); + + /* Close file */ + fclose(fd); + + /* Return loaded ROM size */ + return size; +} + +void osd_input_update(void) +{ + int i, padnum = 0; + unsigned int temp; + + input_poll_cb(); + + for(i = 0; i < MAX_INPUTS; i++) + { + temp = 0; + switch (input.dev[i]) + { + case DEVICE_PAD6B: + { + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L)) + temp |= INPUT_X; + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X)) + temp |= INPUT_Y; + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R)) + temp |= INPUT_Z; + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT)) + temp |= INPUT_MODE; + } + + case DEVICE_PAD3B: + { + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y)) + temp |= INPUT_A; + } + + case DEVICE_PAD2B: + { + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B)) + temp |= INPUT_B; + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A)) + temp |= INPUT_C; + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START)) + temp |= INPUT_START; + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP)) + temp |= INPUT_UP; + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN)) + temp |= INPUT_DOWN; + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT)) + temp |= INPUT_LEFT; + if (input_state_cb(padnum, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT)) + temp |= INPUT_RIGHT; + + padnum++; + break; + } + + default: + break; + } + + input.pad[i] = temp; + } +} + +static void init_bitmap(void) +{ + memset(&bitmap, 0, sizeof(bitmap)); + bitmap.width = 1024; + bitmap.height = 512; + bitmap.pitch = 1024 * 2; + bitmap.data = (uint8_t *)bitmap_data_; + bitmap.viewport.w = 0; + bitmap.viewport.h = 0; + bitmap.viewport.x = 0; + bitmap.viewport.y = 0; +} + +static void config_default(void) +{ + int i; + + /* sound options */ + config.psg_preamp = 150; + config.fm_preamp = 100; + config.hq_fm = 1; /* high-quality resampling */ + config.psgBoostNoise = 1; + config.filter = 0; /* no filter */ + config.lp_range = 0x9999; /* 0.6 in 16.16 fixed point */ + config.low_freq = 880; + config.high_freq = 5000; + config.lg = 1.0; + config.mg = 1.0; + config.hg = 1.0; + config.dac_bits = 14; /* MAX DEPTH */ + config.ym2413 = 2; /* AUTO */ + config.mono = 0; /* STEREO output */ + + /* system options */ + config.system = 0; /* AUTO */ + config.region_detect = 0; /* AUTO */ + config.vdp_mode = 0; /* AUTO */ + config.master_clock = 0; /* AUTO */ + config.force_dtack = 0; + config.addr_error = 1; + config.bios = 0; + config.lock_on = 0; + + /* video options */ + config.overscan = 0; + config.gg_extra = 0; + config.ntsc = 0; + config.render = 0; +} + +static void bram_load(void) +{ + FILE *fp; + + /* automatically load internal backup RAM */ + switch (region_code) + { + case REGION_JAPAN_NTSC: + fp = fopen(CD_BRAM_JP, "rb"); + break; + case REGION_EUROPE: + fp = fopen(CD_BRAM_EU, "rb"); + break; + case REGION_USA: + fp = fopen(CD_BRAM_US, "rb"); + break; + default: + return; + } + + if (fp != NULL) + { + fread(scd.bram, 0x2000, 1, fp); + fclose(fp); + + /* update CRC */ + brm_crc[0] = crc32(0, scd.bram, 0x2000); + } + else + { + /* force internal backup RAM format (does not use previous region backup RAM) */ + scd.bram[0x1fff] = 0; + } + + /* check if internal backup RAM is correctly formatted */ + if (memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20)) + { + /* clear internal backup RAM */ + memset(scd.bram, 0x00, 0x2000 - 0x40); + + /* internal Backup RAM size fields */ + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = 0x00; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (sizeof(scd.bram) / 64) - 3; + + /* format internal backup RAM */ + memcpy(scd.bram + 0x2000 - 0x40, brm_format, 0x40); + + /* clear CRC to force file saving (in case previous region backup RAM was also formatted) */ + brm_crc[0] = 0; + } + + /* automatically load cartridge backup RAM (if enabled) */ + if (scd.cartridge.id) + { + fp = fopen(CART_BRAM, "rb"); + if (fp != NULL) + { + int filesize = scd.cartridge.mask + 1; + int done = 0; + + /* Read into buffer (2k blocks) */ + while (filesize > CHUNKSIZE) + { + fread(scd.cartridge.area + done, CHUNKSIZE, 1, fp); + done += CHUNKSIZE; + filesize -= CHUNKSIZE; + } + + /* Read remaining bytes */ + if (filesize) + { + fread(scd.cartridge.area + done, filesize, 1, fp); + } + + /* close file */ + fclose(fp); + + /* update CRC */ + brm_crc[1] = crc32(0, scd.cartridge.area, scd.cartridge.mask + 1); + } + + /* check if cartridge backup RAM is correctly formatted */ + if (memcmp(scd.cartridge.area + scd.cartridge.mask + 1 - 0x20, brm_format + 0x20, 0x20)) + { + /* clear cartridge backup RAM */ + memset(scd.cartridge.area, 0x00, scd.cartridge.mask + 1); + + /* Cartridge Backup RAM size fields */ + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = (((scd.cartridge.mask + 1) / 64) - 3) >> 8; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (((scd.cartridge.mask + 1) / 64) - 3) & 0xff; + + /* format cartridge backup RAM */ + memcpy(scd.cartridge.area + scd.cartridge.mask + 1 - 0x40, brm_format, 0x40); + } + } +} + +static void bram_save(void) +{ + FILE *fp; + + /* verify that internal backup RAM has been modified */ + if (crc32(0, scd.bram, 0x2000) != brm_crc[0]) + { + /* check if it is correctly formatted before saving */ + if (!memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20)) + { + switch (region_code) + { + case REGION_JAPAN_NTSC: + fp = fopen(CD_BRAM_JP, "wb"); + break; + case REGION_EUROPE: + fp = fopen(CD_BRAM_EU, "wb"); + break; + case REGION_USA: + fp = fopen(CD_BRAM_US, "wb"); + break; + default: + return; + } + + if (fp != NULL) + { + fwrite(scd.bram, 0x2000, 1, fp); + fclose(fp); + + /* update CRC */ + brm_crc[0] = crc32(0, scd.bram, 0x2000); + } + } + } + + /* verify that cartridge backup RAM has been modified */ + if (scd.cartridge.id && (crc32(0, scd.cartridge.area, scd.cartridge.mask + 1) != brm_crc[1])) + { + /* check if it is correctly formatted before saving */ + if (!memcmp(scd.cartridge.area + scd.cartridge.mask + 1 - 0x20, brm_format + 0x20, 0x20)) + { + fp = fopen(CART_BRAM, "wb"); + if (fp != NULL) + { + int filesize = scd.cartridge.mask + 1; + int done = 0; + + /* Write to file (2k blocks) */ + while (filesize > CHUNKSIZE) + { + fwrite(scd.cartridge.area + done, CHUNKSIZE, 1, fp); + done += CHUNKSIZE; + filesize -= CHUNKSIZE; + } + + /* Write remaining bytes */ + if (filesize) + { + fwrite(scd.cartridge.area + done, filesize, 1, fp); + } + + /* Close file */ + fclose(fp); + + /* update CRC */ + brm_crc[1] = crc32(0, scd.cartridge.area, scd.cartridge.mask + 1); + } + } + } +} + +static void extract_directory(char *buf, const char *path, size_t size) +{ + char *base; + strncpy(buf, path, size - 1); + buf[size - 1] = '\0'; + + base = strrchr(buf, '/'); + if (!base) + base = strrchr(buf, '\\'); + + if (base) + *base = '\0'; + else + buf[0] = '\0'; +} + +static void update_viewport(void) +{ + vwidth = bitmap.viewport.w + (bitmap.viewport.x * 2); + vheight = bitmap.viewport.h + (bitmap.viewport.y * 2); + + if (config.ntsc) + { + if (reg[12] & 1) + vwidth = MD_NTSC_OUT_WIDTH(vwidth); + else + vwidth = SMS_NTSC_OUT_WIDTH(vwidth); + } + + if (config.render && interlaced) + { + vheight = vheight * 2; + } +} + +static void check_variables(void) +{ + unsigned orig_value; + bool update_viewports = false; + bool reinit = false; + struct retro_variable var = {0}; + + var.key = "system_hw"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + orig_value = config.system; + if (!strcmp(var.value, "sg-1000")) + config.system = SYSTEM_SG; + else if (!strcmp(var.value, "mark-III")) + config.system = SYSTEM_MARKIII; + else if (!strcmp(var.value, "master system")) + config.system = SYSTEM_SMS; + else if (!strcmp(var.value, "master system II")) + config.system = SYSTEM_SMS2; + else if (!strcmp(var.value, "game gear")) + config.system = SYSTEM_GG; + else if (!strcmp(var.value, "mega drive / genesis")) + config.system = SYSTEM_MD; + else + config.system = 0; + + if (orig_value != config.system) + { + if (system_hw) + { + switch (config.system) + { + case 0: + system_hw = romtype; /* AUTO */ + break; + + case SYSTEM_MD: + system_hw = (romtype & SYSTEM_MD) ? romtype : SYSTEM_PBC; + break; + + case SYSTEM_GG: + system_hw = (romtype == SYSTEM_GG) ? SYSTEM_GG : SYSTEM_GGMS; + break; + + default: + system_hw = config.system; + break; + } + + reinit = true; + } + } + } + + var.key = "region_detect"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + orig_value = config.region_detect; + if (!strcmp(var.value, "ntsc-u")) + config.region_detect = 1; + else if (!strcmp(var.value, "pal")) + config.region_detect = 2; + else if (!strcmp(var.value, "ntsc-j")) + config.region_detect = 3; + else + config.region_detect = 0; + + if (orig_value != config.region_detect) + { + if (system_hw) + { + get_region(NULL); + reinit = true; + } + } + } + + var.key = "force_dtack"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + if (!strcmp(var.value, "enabled")) + config.force_dtack = 1; + else + config.force_dtack = 0; + } + + var.key = "addr_error"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + if (!strcmp(var.value, "enabled")) + m68k.aerr_enabled = config.addr_error = 1; + else + m68k.aerr_enabled = config.addr_error = 0; + } + + var.key = "lock_on"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + orig_value = config.lock_on; + if (!strcmp(var.value, "game genie")) + config.lock_on = TYPE_GG; + else if (!strcmp(var.value, "action replay (pro)")) + config.lock_on = TYPE_AR; + else if (!strcmp(var.value, "sonic & knuckles")) + config.lock_on = TYPE_SK; + else + config.lock_on = 0; + + if (orig_value != config.lock_on) + { + if (system_hw == SYSTEM_MD) + reinit = true; + } + } + + var.key = "ym2413"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + orig_value = config.ym2413; + if (!strcmp(var.value, "enabled")) + config.ym2413 = 1; + else if (!strcmp(var.value, "disabled")) + config.ym2413 = 0; + else + config.ym2413 = 2; + + if (orig_value != config.ym2413) + { + if (system_hw && (config.ym2413 & 2) && ((system_hw & SYSTEM_PBC) != SYSTEM_MD)) + { + memcpy(temp, sram.sram, sizeof(temp)); + sms_cart_init(); + memcpy(sram.sram, temp, sizeof(temp)); + } + } + } + + var.key = "dac_bits"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + if (!strcmp(var.value, "enabled")) + config.dac_bits = 9; + else + config.dac_bits = 14; + + YM2612Config(config.dac_bits); + } + + var.key = "blargg_ntsc_filter"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + orig_value = config.ntsc; + + if (strcmp(var.value, "disabled") == 0) + config.ntsc = 0; + else if (strcmp(var.value, "monochrome") == 0) + { + config.ntsc = 1; + sms_ntsc_init(sms_ntsc, &sms_ntsc_monochrome); + md_ntsc_init(md_ntsc, &md_ntsc_monochrome); + } + else if (strcmp(var.value, "composite") == 0) + { + config.ntsc = 1; + sms_ntsc_init(sms_ntsc, &sms_ntsc_composite); + md_ntsc_init(md_ntsc, &md_ntsc_composite); + } + else if (strcmp(var.value, "svideo") == 0) + { + config.ntsc = 1; + sms_ntsc_init(sms_ntsc, &sms_ntsc_svideo); + md_ntsc_init(md_ntsc, &md_ntsc_svideo); + } + else if (strcmp(var.value, "rgb") == 0) + { + config.ntsc = 1; + sms_ntsc_init(sms_ntsc, &sms_ntsc_rgb); + md_ntsc_init(md_ntsc, &md_ntsc_rgb); + } + + if (orig_value != config.ntsc) + update_viewports = true; + } + + var.key = "overscan"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + orig_value = config.overscan; + if (strcmp(var.value, "disabled") == 0) + config.overscan = 0; + else if (strcmp(var.value, "top/bottom") == 0) + config.overscan = 1; + else if (strcmp(var.value, "left/right") == 0) + config.overscan = 2; + else if (strcmp(var.value, "full") == 0) + config.overscan = 3; + if (orig_value != config.overscan) + update_viewports = true; + } + + var.key = "gg_extra"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + orig_value = config.gg_extra; + if (strcmp(var.value, "disabled") == 0) + config.gg_extra = 0; + else if (strcmp(var.value, "enabled") == 0) + config.gg_extra = 1; + if (orig_value != config.gg_extra) + update_viewports = true; + } + + var.key = "render"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + orig_value = config.render; + if (strcmp(var.value, "normal") == 0) + config.render = 0; + else + config.render = 1; + if (orig_value != config.render) + update_viewports = true; + } + + if (reinit) + { + audio_init(44100, snd.frame_rate); + memcpy(temp, sram.sram, sizeof(temp)); + system_init(); + system_reset(); + memcpy(sram.sram, temp, sizeof(temp)); + } + + if (update_viewports) + { + bitmap.viewport.changed = 3; + if ((system_hw == SYSTEM_GG) && !config.gg_extra) + bitmap.viewport.x = (config.overscan & 2) ? 14 : -48; + else + bitmap.viewport.x = (config.overscan & 2) * 7; + } +} + +static void configure_controls(void) +{ + int i; + struct retro_variable var; + + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MD_GAMEPAD; + + var.key = "padtype"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + if (!strcmp(var.value, "6-buttons")) + for(i = 0; i < MAX_INPUTS; i++) + config.input[i].padtype = DEVICE_PAD6B; + else if (!strcmp(var.value, "3-buttons")) + for(i = 0; i < MAX_INPUTS; i++) + config.input[i].padtype = DEVICE_PAD3B; + else if (!strcmp(var.value, "2-buttons")) + for(i = 0; i < MAX_INPUTS; i++) + config.input[i].padtype = DEVICE_PAD2B; + else if ((system_hw & SYSTEM_PBC) != SYSTEM_MD) + for(i = 0; i < MAX_INPUTS; i++) + config.input[i].padtype = DEVICE_PAD2B; + else if (rominfo.peripherals & 2) + for(i = 0; i < MAX_INPUTS; i++) + config.input[i].padtype = DEVICE_PAD6B; + else + for(i = 0; i < MAX_INPUTS; i++) + config.input[i].padtype = DEVICE_PAD3B; + + var.key = "multitap"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + if (!strcmp(var.value, "4-wayplay")) + input.system[0] = input.system[1] = SYSTEM_WAYPLAY; + else if (!strcmp(var.value, "teamplayer 1")) + input.system[0] = SYSTEM_TEAMPLAYER; + else if (!strcmp(var.value, "teamplayer 2")) + input.system[1] = SYSTEM_TEAMPLAYER; + else if (!strcmp(var.value, "teamplayer 1&2")) + input.system[0] = input.system[1] = SYSTEM_TEAMPLAYER; + + var.key = "portb"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + if (!strcmp(var.value, "disabled")) + input.system[1] = NO_SYSTEM; + + input_init(); +} + +/************************************ + * libretro implementation + ************************************/ +unsigned retro_api_version(void) { return RETRO_API_VERSION; } + +void retro_set_environment(retro_environment_t cb) +{ + static const struct retro_variable vars[] = { + { "system_hw", "System hardware; auto|sg-1000|mark-III|master system|master system II|game gear|mega drive / genesis" }, + { "region_detect", "System region; auto|ntsc-u|pal|ntsc-j" }, + { "force_dtack", "System lockups; enabled|disabled" }, + { "addr_error", "68k address error; enabled|disabled" }, + { "lock_on", "Cartridge lock-on; disabled|game genie|action replay (pro)|sonic & knuckles" }, + { "padtype", "Gamepad type; auto|6-buttons|3-buttons|2-buttons" }, + { "multitap", "Multi Tap; disabled|4-wayplay|teamplayer (port 1)|teamplayer (port 2)|teamplayer (both)" }, + { "portb", "Control Port 2; enabled|disabled" }, + { "ym2413", "Master System FM; auto|disabled|enabled" }, + { "dac_bits", "YM2612 DAC quantization; disabled|enabled" }, + { "blargg_ntsc_filter", "Blargg NTSC filter; disabled|monochrome|composite|svideo|rgb" }, + { "overscan", "Borders; disabled|top/bottom|left/right|full" }, + { "gg_extra", "Game Gear extended screen; disabled|enabled" }, + { "render", "Interlaced mode resolution; normal|double" }, + { NULL, NULL }, + }; + + environ_cb = cb; + cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars); +} + +void retro_set_video_refresh(retro_video_refresh_t cb) { video_cb = cb; } +void retro_set_audio_sample(retro_audio_sample_t cb) { (void)cb; } +void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { audio_cb = cb; } +void retro_set_input_poll(retro_input_poll_t cb) { input_poll_cb = cb; } +void retro_set_input_state(retro_input_state_t cb) { input_state_cb = cb; } + +void retro_get_system_info(struct retro_system_info *info) +{ + info->library_name = "Genesis Plus GX"; + info->library_version = "v1.7.4"; + info->valid_extensions = "mdx|md|smd|gen|bin|cue|iso|sms|gg|sg"; + info->block_extract = false; + info->need_fullpath = true; +} + +void retro_get_system_av_info(struct retro_system_av_info *info) +{ + info->geometry.base_width = vwidth; + info->geometry.base_height = vheight; + info->geometry.max_width = 1024; + info->geometry.max_height = 512; + info->geometry.aspect_ratio = 4.0 / 3.0; + info->timing.fps = snd.frame_rate; + info->timing.sample_rate = 44100; +} + +void retro_set_controller_port_device(unsigned port, unsigned device) +{ + (void)port; + (void)device; +} + +size_t retro_serialize_size(void) { return STATE_SIZE; } + +bool retro_serialize(void *data, size_t size) +{ + if (size != STATE_SIZE) + return FALSE; + + state_save(data); + + return TRUE; +} + +bool retro_unserialize(const void *data, size_t size) +{ + if (size != STATE_SIZE) + return FALSE; + + if (!state_load((uint8_t*)data)) + return FALSE; + + return TRUE; +} + +void retro_cheat_reset(void) {} +void retro_cheat_set(unsigned index, bool enabled, const char *code) +{ + (void)index; + (void)enabled; + (void)code; +} + +bool retro_load_game(const struct retro_game_info *info) +{ + int i; + const char *dir; +#if defined(_WIN32) + char slash = '\\'; +#else + char slash = '/'; +#endif + + extract_directory(g_rom_dir, info->path, sizeof(g_rom_dir)); + + if (!environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) || !dir) + { + fprintf(stderr, "[genplus]: Defaulting system directory to %s.\n", g_rom_dir); + dir = g_rom_dir; + } + + snprintf(GG_ROM, sizeof(GG_ROM), "%s%cggenie.bin", dir, slash); + snprintf(AR_ROM, sizeof(AR_ROM), "%s%careplay.bin", dir, slash); + snprintf(SK_ROM, sizeof(SK_ROM), "%s%csk.bin", dir, slash); + snprintf(SK_UPMEM, sizeof(SK_UPMEM), "%s%cs2k.bin", dir, slash); + snprintf(CD_BIOS_EU, sizeof(CD_BIOS_EU), "%s%cbios_CD_E.bin", dir, slash); + snprintf(CD_BIOS_US, sizeof(CD_BIOS_US), "%s%cbios_CD_U.bin", dir, slash); + snprintf(CD_BIOS_JP, sizeof(CD_BIOS_JP), "%s%cbios_CD_J.bin", dir, slash); + snprintf(CD_BRAM_EU, sizeof(CD_BRAM_EU), "%s%cscd_E.brm", dir, slash); + snprintf(CD_BRAM_US, sizeof(CD_BRAM_US), "%s%cscd_U.brm", dir, slash); + snprintf(CD_BRAM_JP, sizeof(CD_BRAM_JP), "%s%cscd_J.brm", dir, slash); + snprintf(CART_BRAM, sizeof(CART_BRAM), "%s%ccart.brm", dir, slash); + fprintf(stderr, "Game Genie ROM should be located at: %s\n", GG_ROM); + fprintf(stderr, "Action Replay (Pro) ROM should be located at: %s\n", AR_ROM); + fprintf(stderr, "Sonic & Knuckles (2 MB) ROM should be located at: %s\n", SK_ROM); + fprintf(stderr, "Sonic & Knuckles UPMEM (256 KB) ROM should be located at: %s\n", SK_UPMEM); + fprintf(stderr, "Mega CD PAL BIOS should be located at: %s\n", CD_BIOS_EU); + fprintf(stderr, "Sega CD NTSC-U BIOS should be located at: %s\n", CD_BIOS_US); + fprintf(stderr, "Mega CD NTSC-J BIOS should be located at: %s\n", CD_BIOS_JP); + fprintf(stderr, "Mega CD PAL BRAM is located at: %s\n", CD_BRAM_EU); + fprintf(stderr, "Sega CD NTSC-U BRAM is located at: %s\n", CD_BRAM_US); + fprintf(stderr, "Mega CD NTSC-J BRAM is located at: %s\n", CD_BRAM_JP); + fprintf(stderr, "Mega CD RAM CART is located at: %s\n", CART_BRAM); + + check_variables(); + if (!load_rom((char *)info->path)) + return false; + + configure_controls(); + + audio_init(44100, vdp_pal ? pal_fps : ntsc_fps); + system_init(); + system_reset(); + + if (system_hw == SYSTEM_MCD) + bram_load(); + + update_viewport(); + + return true; +} + +bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info) +{ + (void)game_type; + (void)info; + (void)num_info; + return FALSE; +} + +void retro_unload_game(void) +{ + if (system_hw == SYSTEM_MCD) + bram_save(); +} + +unsigned retro_get_region(void) { return vdp_pal ? RETRO_REGION_PAL : RETRO_REGION_NTSC; } + +void *retro_get_memory_data(unsigned id) +{ + if (!sram.on) + return NULL; + + switch (id) + { + case RETRO_MEMORY_SAVE_RAM: + return sram.sram; + + default: + return NULL; + } +} + +size_t retro_get_memory_size(unsigned id) +{ + if (!sram.on) + return 0; + + switch (id) + { + case RETRO_MEMORY_SAVE_RAM: + return 0x10000; + + default: + return 0; + } +} + +void retro_init(void) +{ + unsigned level, rgb565; + sms_ntsc = calloc(1, sizeof(sms_ntsc_t)); + md_ntsc = calloc(1, sizeof(md_ntsc_t)); + + init_bitmap(); + config_default(); + + level = 1; + environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level); + +#ifdef FRONTEND_SUPPORTS_RGB565 + rgb565 = RETRO_PIXEL_FORMAT_RGB565; + if(environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb565)) + fprintf(stderr, "Frontend supports RGB565 - will use that instead of XRGB1555.\n"); +#endif +} + +void retro_deinit(void) +{ + audio_shutdown(); + free(md_ntsc); + free(sms_ntsc); +} + +void retro_reset(void) { system_reset(); } + +void retro_run(void) +{ + bool updated = false; + + if (system_hw == SYSTEM_MCD) + system_frame_scd(0); + else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + system_frame_gen(0); + else + system_frame_sms(0); + + if (bitmap.viewport.changed & 1) + { + bitmap.viewport.changed &= ~1; + update_viewport(); + } + + video_cb(bitmap.data, vwidth, vheight, 1024 * 2); + audio_cb(soundbuffer, audio_update(soundbuffer)); + + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated); + if (updated) + { + check_variables(); + configure_controls(); + } +} diff --git a/genplus-gx/libretro/libretro.h b/genplus-gx/libretro/libretro.h new file mode 100644 index 0000000000..8a29f05ff4 --- /dev/null +++ b/genplus-gx/libretro/libretro.h @@ -0,0 +1,758 @@ +#ifndef LIBRETRO_H__ +#define LIBRETRO_H__ + +#include +#include +#include + +// Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant. +#ifdef __cplusplus +extern "C" { +#else +#if defined(_MSC_VER) && !defined(SN_TARGET_PS3) && !defined(__cplusplus) +#define bool unsigned char +#define true 1 +#define false 0 +#else +#include +#endif +#endif + +// Used for checking API/ABI mismatches that can break libretro implementations. +// It is not incremented for compatible changes to the API. +#define RETRO_API_VERSION 1 + +// Libretro's fundamental device abstractions. +#define RETRO_DEVICE_MASK 0xff +#define RETRO_DEVICE_NONE 0 + +// The JOYPAD is called RetroPad. It is essentially a Super Nintendo controller, +// but with additional L2/R2/L3/R3 buttons, similar to a PS1 DualShock. +#define RETRO_DEVICE_JOYPAD 1 + +// The mouse is a simple mouse, similar to Super Nintendo's mouse. +// X and Y coordinates are reported relatively to last poll (poll callback). +// It is up to the libretro implementation to keep track of where the mouse pointer is supposed to be on the screen. +// The frontend must make sure not to interfere with its own hardware mouse pointer. +#define RETRO_DEVICE_MOUSE 2 + +// KEYBOARD device lets one poll for raw key pressed. +// It is poll based, so input callback will return with the current pressed state. +#define RETRO_DEVICE_KEYBOARD 3 + +// Lightgun X/Y coordinates are reported relatively to last poll, similar to mouse. +#define RETRO_DEVICE_LIGHTGUN 4 + +// The ANALOG device is an extension to JOYPAD (RetroPad). +// Similar to DualShock it adds two analog sticks. +// This is treated as a separate device type as it returns values in the full analog range +// of [-0x8000, 0x7fff]. Positive X axis is right. Positive Y axis is down. +// Only use ANALOG type when polling for analog values of the axes. +#define RETRO_DEVICE_ANALOG 5 + +// Abstracts the concept of a pointing mechanism, e.g. touch. +// This allows libretro to query in absolute coordinates where on the screen a mouse (or something similar) is being placed. +// For a touch centric device, coordinates reported are the coordinates of the press. +// +// Coordinates in X and Y are reported as: +// [-0x7fff, 0x7fff]: -0x7fff corresponds to the far left/top of the screen, +// and 0x7fff corresponds to the far right/bottom of the screen. +// The "screen" is here defined as area that is passed to the frontend and later displayed on the monitor. +// The frontend is free to scale/resize this screen as it sees fit, however, +// (X, Y) = (-0x7fff, -0x7fff) will correspond to the top-left pixel of the game image, etc. +// +// To check if the pointer coordinates are valid (e.g. a touch display actually being touched), +// PRESSED returns 1 or 0. +// If using a mouse, PRESSED will usually correspond to the left mouse button. +// PRESSED will only return 1 if the pointer is inside the game screen. +// +// For multi-touch, the index variable can be used to successively query more presses. +// If index = 0 returns true for _PRESSED, coordinates can be extracted +// with _X, _Y for index = 0. One can then query _PRESSED, _X, _Y with index = 1, and so on. +// Eventually _PRESSED will return false for an index. No further presses are registered at this point. +#define RETRO_DEVICE_POINTER 6 + +// These device types are specializations of the base types above. +// They should only be used in retro_set_controller_type() to inform libretro implementations +// about use of a very specific device type. +// +// In input state callback, however, only the base type should be used in the 'device' field. +#define RETRO_DEVICE_JOYPAD_MULTITAP ((1 << 8) | RETRO_DEVICE_JOYPAD) +#define RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE ((1 << 8) | RETRO_DEVICE_LIGHTGUN) +#define RETRO_DEVICE_LIGHTGUN_JUSTIFIER ((2 << 8) | RETRO_DEVICE_LIGHTGUN) +#define RETRO_DEVICE_LIGHTGUN_JUSTIFIERS ((3 << 8) | RETRO_DEVICE_LIGHTGUN) + +// Buttons for the RetroPad (JOYPAD). +// The placement of these is equivalent to placements on the Super Nintendo controller. +// L2/R2/L3/R3 buttons correspond to the PS1 DualShock. +#define RETRO_DEVICE_ID_JOYPAD_B 0 +#define RETRO_DEVICE_ID_JOYPAD_Y 1 +#define RETRO_DEVICE_ID_JOYPAD_SELECT 2 +#define RETRO_DEVICE_ID_JOYPAD_START 3 +#define RETRO_DEVICE_ID_JOYPAD_UP 4 +#define RETRO_DEVICE_ID_JOYPAD_DOWN 5 +#define RETRO_DEVICE_ID_JOYPAD_LEFT 6 +#define RETRO_DEVICE_ID_JOYPAD_RIGHT 7 +#define RETRO_DEVICE_ID_JOYPAD_A 8 +#define RETRO_DEVICE_ID_JOYPAD_X 9 +#define RETRO_DEVICE_ID_JOYPAD_L 10 +#define RETRO_DEVICE_ID_JOYPAD_R 11 +#define RETRO_DEVICE_ID_JOYPAD_L2 12 +#define RETRO_DEVICE_ID_JOYPAD_R2 13 +#define RETRO_DEVICE_ID_JOYPAD_L3 14 +#define RETRO_DEVICE_ID_JOYPAD_R3 15 + +// Index / Id values for ANALOG device. +#define RETRO_DEVICE_INDEX_ANALOG_LEFT 0 +#define RETRO_DEVICE_INDEX_ANALOG_RIGHT 1 +#define RETRO_DEVICE_ID_ANALOG_X 0 +#define RETRO_DEVICE_ID_ANALOG_Y 1 + +// Id values for MOUSE. +#define RETRO_DEVICE_ID_MOUSE_X 0 +#define RETRO_DEVICE_ID_MOUSE_Y 1 +#define RETRO_DEVICE_ID_MOUSE_LEFT 2 +#define RETRO_DEVICE_ID_MOUSE_RIGHT 3 + +// Id values for LIGHTGUN types. +#define RETRO_DEVICE_ID_LIGHTGUN_X 0 +#define RETRO_DEVICE_ID_LIGHTGUN_Y 1 +#define RETRO_DEVICE_ID_LIGHTGUN_TRIGGER 2 +#define RETRO_DEVICE_ID_LIGHTGUN_CURSOR 3 +#define RETRO_DEVICE_ID_LIGHTGUN_TURBO 4 +#define RETRO_DEVICE_ID_LIGHTGUN_PAUSE 5 +#define RETRO_DEVICE_ID_LIGHTGUN_START 6 + +// Id values for POINTER. +#define RETRO_DEVICE_ID_POINTER_X 0 +#define RETRO_DEVICE_ID_POINTER_Y 1 +#define RETRO_DEVICE_ID_POINTER_PRESSED 2 + +// Returned from retro_get_region(). +#define RETRO_REGION_NTSC 0 +#define RETRO_REGION_PAL 1 + +// Passed to retro_get_memory_data/size(). +// If the memory type doesn't apply to the implementation NULL/0 can be returned. +#define RETRO_MEMORY_MASK 0xff + +// Regular save ram. This ram is usually found on a game cartridge, backed up by a battery. +// If save game data is too complex for a single memory buffer, +// the SYSTEM_DIRECTORY environment callback can be used. +#define RETRO_MEMORY_SAVE_RAM 0 + +// Some games have a built-in clock to keep track of time. +// This memory is usually just a couple of bytes to keep track of time. +#define RETRO_MEMORY_RTC 1 + +// System ram lets a frontend peek into a game systems main RAM. +#define RETRO_MEMORY_SYSTEM_RAM 2 + +// Video ram lets a frontend peek into a game systems video RAM (VRAM). +#define RETRO_MEMORY_VIDEO_RAM 3 + +// Special memory types. +#define RETRO_MEMORY_SNES_BSX_RAM ((1 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_BSX_PRAM ((2 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM ((3 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM ((4 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_GAME_BOY_RAM ((5 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_GAME_BOY_RTC ((6 << 8) | RETRO_MEMORY_RTC) + +// Special game types passed into retro_load_game_special(). +// Only used when multiple ROMs are required. +#define RETRO_GAME_TYPE_BSX 0x101 +#define RETRO_GAME_TYPE_BSX_SLOTTED 0x102 +#define RETRO_GAME_TYPE_SUFAMI_TURBO 0x103 +#define RETRO_GAME_TYPE_SUPER_GAME_BOY 0x104 + +// Keysyms used for ID in input state callback when polling RETRO_KEYBOARD. +enum retro_key +{ + RETROK_UNKNOWN = 0, + RETROK_FIRST = 0, + RETROK_BACKSPACE = 8, + RETROK_TAB = 9, + RETROK_CLEAR = 12, + RETROK_RETURN = 13, + RETROK_PAUSE = 19, + RETROK_ESCAPE = 27, + RETROK_SPACE = 32, + RETROK_EXCLAIM = 33, + RETROK_QUOTEDBL = 34, + RETROK_HASH = 35, + RETROK_DOLLAR = 36, + RETROK_AMPERSAND = 38, + RETROK_QUOTE = 39, + RETROK_LEFTPAREN = 40, + RETROK_RIGHTPAREN = 41, + RETROK_ASTERISK = 42, + RETROK_PLUS = 43, + RETROK_COMMA = 44, + RETROK_MINUS = 45, + RETROK_PERIOD = 46, + RETROK_SLASH = 47, + RETROK_0 = 48, + RETROK_1 = 49, + RETROK_2 = 50, + RETROK_3 = 51, + RETROK_4 = 52, + RETROK_5 = 53, + RETROK_6 = 54, + RETROK_7 = 55, + RETROK_8 = 56, + RETROK_9 = 57, + RETROK_COLON = 58, + RETROK_SEMICOLON = 59, + RETROK_LESS = 60, + RETROK_EQUALS = 61, + RETROK_GREATER = 62, + RETROK_QUESTION = 63, + RETROK_AT = 64, + RETROK_LEFTBRACKET = 91, + RETROK_BACKSLASH = 92, + RETROK_RIGHTBRACKET = 93, + RETROK_CARET = 94, + RETROK_UNDERSCORE = 95, + RETROK_BACKQUOTE = 96, + RETROK_a = 97, + RETROK_b = 98, + RETROK_c = 99, + RETROK_d = 100, + RETROK_e = 101, + RETROK_f = 102, + RETROK_g = 103, + RETROK_h = 104, + RETROK_i = 105, + RETROK_j = 106, + RETROK_k = 107, + RETROK_l = 108, + RETROK_m = 109, + RETROK_n = 110, + RETROK_o = 111, + RETROK_p = 112, + RETROK_q = 113, + RETROK_r = 114, + RETROK_s = 115, + RETROK_t = 116, + RETROK_u = 117, + RETROK_v = 118, + RETROK_w = 119, + RETROK_x = 120, + RETROK_y = 121, + RETROK_z = 122, + RETROK_DELETE = 127, + + RETROK_KP0 = 256, + RETROK_KP1 = 257, + RETROK_KP2 = 258, + RETROK_KP3 = 259, + RETROK_KP4 = 260, + RETROK_KP5 = 261, + RETROK_KP6 = 262, + RETROK_KP7 = 263, + RETROK_KP8 = 264, + RETROK_KP9 = 265, + RETROK_KP_PERIOD = 266, + RETROK_KP_DIVIDE = 267, + RETROK_KP_MULTIPLY = 268, + RETROK_KP_MINUS = 269, + RETROK_KP_PLUS = 270, + RETROK_KP_ENTER = 271, + RETROK_KP_EQUALS = 272, + + RETROK_UP = 273, + RETROK_DOWN = 274, + RETROK_RIGHT = 275, + RETROK_LEFT = 276, + RETROK_INSERT = 277, + RETROK_HOME = 278, + RETROK_END = 279, + RETROK_PAGEUP = 280, + RETROK_PAGEDOWN = 281, + + RETROK_F1 = 282, + RETROK_F2 = 283, + RETROK_F3 = 284, + RETROK_F4 = 285, + RETROK_F5 = 286, + RETROK_F6 = 287, + RETROK_F7 = 288, + RETROK_F8 = 289, + RETROK_F9 = 290, + RETROK_F10 = 291, + RETROK_F11 = 292, + RETROK_F12 = 293, + RETROK_F13 = 294, + RETROK_F14 = 295, + RETROK_F15 = 296, + + RETROK_NUMLOCK = 300, + RETROK_CAPSLOCK = 301, + RETROK_SCROLLOCK = 302, + RETROK_RSHIFT = 303, + RETROK_LSHIFT = 304, + RETROK_RCTRL = 305, + RETROK_LCTRL = 306, + RETROK_RALT = 307, + RETROK_LALT = 308, + RETROK_RMETA = 309, + RETROK_LMETA = 310, + RETROK_LSUPER = 311, + RETROK_RSUPER = 312, + RETROK_MODE = 313, + RETROK_COMPOSE = 314, + + RETROK_HELP = 315, + RETROK_PRINT = 316, + RETROK_SYSREQ = 317, + RETROK_BREAK = 318, + RETROK_MENU = 319, + RETROK_POWER = 320, + RETROK_EURO = 321, + RETROK_UNDO = 322, + + RETROK_LAST, + + RETROK_DUMMY = INT_MAX // Ensure sizeof(enum) == sizeof(int) +}; + +enum retro_mod +{ + RETROKMOD_NONE = 0x0000, + + RETROKMOD_SHIFT = 0x01, + RETROKMOD_CTRL = 0x02, + RETROKMOD_ALT = 0x04, + RETROKMOD_META = 0x08, + + RETROKMOD_NUMLOCK = 0x10, + RETROKMOD_CAPSLOCK = 0x20, + RETROKMOD_SCROLLOCK = 0x40, + + RETROKMOD_DUMMY = INT_MAX // Ensure sizeof(enum) == sizeof(int) +}; + +// If set, this call is not part of the public libretro API yet. It can change or be removed at any time. +#define RETRO_ENVIRONMENT_EXPERIMENTAL 0x10000 + +// Environment commands. +#define RETRO_ENVIRONMENT_SET_ROTATION 1 // const unsigned * -- + // Sets screen rotation of graphics. + // Is only implemented if rotation can be accelerated by hardware. + // Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180, 270 degrees + // counter-clockwise respectively. + // +#define RETRO_ENVIRONMENT_GET_OVERSCAN 2 // bool * -- + // Boolean value whether or not the implementation should use overscan, or crop away overscan. + // +#define RETRO_ENVIRONMENT_GET_CAN_DUPE 3 // bool * -- + // Boolean value whether or not frontend supports frame duping, + // passing NULL to video frame callback. + // +// Environ 4, 5 are no longer supported (GET_VARIABLE / SET_VARIABLES), and reserved to avoid possible ABI clash. +#define RETRO_ENVIRONMENT_SET_MESSAGE 6 // const struct retro_message * -- + // Sets a message to be displayed in implementation-specific manner for a certain amount of 'frames'. + // Should not be used for trivial messages, which should simply be logged to stderr. +#define RETRO_ENVIRONMENT_SHUTDOWN 7 // N/A (NULL) -- + // Requests the frontend to shutdown. + // Should only be used if game has a specific + // way to shutdown the game from a menu item or similar. + // +#define RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL 8 + // const unsigned * -- + // Gives a hint to the frontend how demanding this implementation + // is on a system. E.g. reporting a level of 2 means + // this implementation should run decently on all frontends + // of level 2 and up. + // + // It can be used by the frontend to potentially warn + // about too demanding implementations. + // + // The levels are "floating", but roughly defined as: + // 0: Low-powered embedded devices such as Raspberry Pi + // 1: 6th generation consoles, such as Wii/Xbox 1, and phones, tablets, etc. + // 2: 7th generation consoles, such as PS3/360, with sub-par CPUs. + // 3: Modern desktop/laptops with reasonably powerful CPUs. + // 4: High-end desktops with very powerful CPUs. + // + // This function can be called on a per-game basis, + // as certain games an implementation can play might be + // particularily demanding. + // If called, it should be called in retro_load_game(). + // +#define RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY 9 + // const char ** -- + // Returns the "system" directory of the frontend. + // This directory can be used to store system specific ROMs such as BIOSes, configuration data, etc. + // The returned value can be NULL. + // If so, no such directory is defined, + // and it's up to the implementation to find a suitable directory. + // +#define RETRO_ENVIRONMENT_SET_PIXEL_FORMAT 10 + // const enum retro_pixel_format * -- + // Sets the internal pixel format used by the implementation. + // The default pixel format is RETRO_PIXEL_FORMAT_0RGB1555. + // This pixel format however, is deprecated (see enum retro_pixel_format). + // If the call returns false, the frontend does not support this pixel format. + // This function should be called inside retro_load_game() or retro_get_system_av_info(). + // +#define RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS 11 + // const struct retro_input_descriptor * -- + // Sets an array of retro_input_descriptors. + // It is up to the frontend to present this in a usable way. + // The array is terminated by retro_input_descriptor::description being set to NULL. + // This function can be called at any time, but it is recommended to call it as early as possible. +#define RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK 12 + // const struct retro_keyboard_callback * -- + // Sets a callback function used to notify core about keyboard events. + // +#define RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE 13 + // const struct retro_disk_control_callback * -- + // Sets an interface which frontend can use to eject and insert disk images. + // This is used for games which consist of multiple images and must be manually + // swapped out by the user (e.g. PSX). +#define RETRO_ENVIRONMENT_SET_HW_RENDER (14 | RETRO_ENVIRONMENT_EXPERIMENTAL) + // struct retro_hw_render_callback * -- + // NOTE: This call is currently very experimental, and should not be considered part of the public API. + // The interface could be changed or removed at any time. + // Sets an interface to let a libretro core render with hardware acceleration. + // Should be called in retro_load_game(). + // If successful, libretro cores will be able to render to a frontend-provided framebuffer. + // The size of this framebuffer will be at least as large as max_width/max_height provided in get_av_info(). + // If HW rendering is used, pass only RETRO_HW_FRAME_BUFFER_VALID or NULL to retro_video_refresh_t. +#define RETRO_ENVIRONMENT_GET_VARIABLE 15 + // struct retro_variable * -- + // Interface to aquire user-defined information from environment + // that cannot feasibly be supported in a multi-system way. + // 'key' should be set to a key which has already been set by SET_VARIABLES. + // 'data' will be set to a value or NULL. + // +#define RETRO_ENVIRONMENT_SET_VARIABLES 16 + // const struct retro_variable * -- + // Allows an implementation to signal the environment + // which variables it might want to check for later using GET_VARIABLE. + // This allows the frontend to present these variables to a user dynamically. + // This should be called as early as possible (ideally in retro_set_environment). + // + // 'data' points to an array of retro_variable structs terminated by a { NULL, NULL } element. + // retro_variable::key should be namespaced to not collide with other implementations' keys. E.g. A core called 'foo' should use keys named as 'foo_option'. + // retro_variable::value should contain a human readable description of the key as well as a '|' delimited list of expected values. + // The number of possible options should be very limited, i.e. it should be feasible to cycle through options without a keyboard. + // First entry should be treated as a default. + // + // Example entry: + // { "foo_option", "Speed hack coprocessor X; false|true" } + // + // Text before first ';' is description. This ';' must be followed by a space, and followed by a list of possible values split up with '|'. + // Only strings are operated on. The possible values will generally be displayed and stored as-is by the frontend. + // +#define RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE 17 + // bool * -- + // Result is set to true if some variables are updated by + // frontend since last call to RETRO_ENVIRONMENT_GET_VARIABLE. + // Variables should be queried with GET_VARIABLE. + +// Pass this to retro_video_refresh_t if rendering to hardware. +// Passing NULL to retro_video_refresh_t is still a frame dupe as normal. +#define RETRO_HW_FRAME_BUFFER_VALID ((void*)-1) + +// Invalidates the current HW context. +// If called, all GPU resources must be reinitialized. +// Usually called when frontend reinits video driver. +// Also called first time video driver is initialized, allowing libretro core to init resources. +typedef void (*retro_hw_context_reset_t)(void); +// Gets current framebuffer which is to be rendered to. Could change every frame potentially. +typedef uintptr_t (*retro_hw_get_current_framebuffer_t)(void); + +// Get a symbol from HW context. +typedef void (*retro_proc_address_t)(void); +typedef retro_proc_address_t (*retro_hw_get_proc_address_t)(const char *sym); + +enum retro_hw_context_type +{ + RETRO_HW_CONTEXT_NONE = 0, + RETRO_HW_CONTEXT_OPENGL, // OpenGL 2.x. Latest version available before 3.x+. + RETRO_HW_CONTEXT_OPENGLES2, // GLES 2.0 + + RETRO_HW_CONTEXT_DUMMY = INT_MAX +}; + +struct retro_hw_render_callback +{ + enum retro_hw_context_type context_type; // Which API to use. Set by libretro core. + retro_hw_context_reset_t context_reset; // Set by libretro core. + retro_hw_get_current_framebuffer_t get_current_framebuffer; // Set by frontend. + retro_hw_get_proc_address_t get_proc_address; // Set by frontend. + bool depth; // Set if render buffers should have depth component attached. +}; + +// Callback type passed in RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK. Called by the frontend in response to keyboard events. +// down is set if the key is being pressed, or false if it is being released. +// keycode is the RETROK value of the char. +// character is the text character of the pressed key. (UTF-32). +// key_modifiers is a set of RETROKMOD values or'ed together. +typedef void (*retro_keyboard_event_t)(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers); + +struct retro_keyboard_callback +{ + retro_keyboard_event_t callback; +}; + +// Callbacks for RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE. +// Should be set for implementations which can swap out multiple disk images in runtime. +// If the implementation can do this automatically, it should strive to do so. +// However, there are cases where the user must manually do so. +// +// Overview: To swap a disk image, eject the disk image with set_eject_state(true). +// Set the disk index with set_image_index(index). Insert the disk again with set_eject_state(false). + +// If ejected is true, "ejects" the virtual disk tray. +// When ejected, the disk image index can be set. +typedef bool (*retro_set_eject_state_t)(bool ejected); +// Gets current eject state. The initial state is 'not ejected'. +typedef bool (*retro_get_eject_state_t)(void); +// Gets current disk index. First disk is index 0. +// If return value is >= get_num_images(), no disk is currently inserted. +typedef unsigned (*retro_get_image_index_t)(void); +// Sets image index. Can only be called when disk is ejected. +// The implementation supports setting "no disk" by using an index >= get_num_images(). +typedef bool (*retro_set_image_index_t)(unsigned index); +// Gets total number of images which are available to use. +typedef unsigned (*retro_get_num_images_t)(void); +// +// Replaces the disk image associated with index. +// Arguments to pass in info have same requirements as retro_load_game(). +// Virtual disk tray must be ejected when calling this. +// Replacing a disk image with info = NULL will remove the disk image from the internal list. +// As a result, calls to get_image_index() can change. +// +// E.g. replace_image_index(1, NULL), and previous get_image_index() returned 4 before. +// Index 1 will be removed, and the new index is 3. +struct retro_game_info; +typedef bool (*retro_replace_image_index_t)(unsigned index, const struct retro_game_info *info); +// Adds a new valid index (get_num_images()) to the internal disk list. +// This will increment subsequent return values from get_num_images() by 1. +// This image index cannot be used until a disk image has been set with replace_image_index. +typedef bool (*retro_add_image_index_t)(void); + +struct retro_disk_control_callback +{ + retro_set_eject_state_t set_eject_state; + retro_get_eject_state_t get_eject_state; + + retro_get_image_index_t get_image_index; + retro_set_image_index_t set_image_index; + retro_get_num_images_t get_num_images; + + retro_replace_image_index_t replace_image_index; + retro_add_image_index_t add_image_index; +}; + +enum retro_pixel_format +{ + // 0RGB1555, native endian. 0 bit must be set to 0. + // This pixel format is default for compatibility concerns only. + // If a 15/16-bit pixel format is desired, consider using RGB565. + RETRO_PIXEL_FORMAT_0RGB1555 = 0, + + // XRGB8888, native endian. X bits are ignored. + RETRO_PIXEL_FORMAT_XRGB8888 = 1, + + // RGB565, native endian. This pixel format is the recommended format to use if a 15/16-bit format is desired + // as it is the pixel format that is typically available on a wide range of low-power devices. + // It is also natively supported in APIs like OpenGL ES. + RETRO_PIXEL_FORMAT_RGB565 = 2, + + // Ensure sizeof() == sizeof(int). + RETRO_PIXEL_FORMAT_UNKNOWN = INT_MAX +}; + +struct retro_message +{ + const char *msg; // Message to be displayed. + unsigned frames; // Duration in frames of message. +}; + +// Describes how the libretro implementation maps a libretro input bind +// to its internal input system through a human readable string. +// This string can be used to better let a user configure input. +struct retro_input_descriptor +{ + // Associates given parameters with a description. + unsigned port; + unsigned device; + unsigned index; + unsigned id; + + const char *description; // Human readable description for parameters. + // The pointer must remain valid until retro_unload_game() is called. +}; + +struct retro_system_info +{ + // All pointers are owned by libretro implementation, and pointers must remain valid until retro_deinit() is called. + + const char *library_name; // Descriptive name of library. Should not contain any version numbers, etc. + const char *library_version; // Descriptive version of core. + + const char *valid_extensions; // A string listing probably rom extensions the core will be able to load, separated with pipe. + // I.e. "bin|rom|iso". + // Typically used for a GUI to filter out extensions. + + bool need_fullpath; // If true, retro_load_game() is guaranteed to provide a valid pathname in retro_game_info::path. + // ::data and ::size are both invalid. + // If false, ::data and ::size are guaranteed to be valid, but ::path might not be valid. + // This is typically set to true for libretro implementations that must load from file. + // Implementations should strive for setting this to false, as it allows the frontend to perform patching, etc. + + bool block_extract; // If true, the frontend is not allowed to extract any archives before loading the real ROM. + // Necessary for certain libretro implementations that load games from zipped archives. +}; + +struct retro_game_geometry +{ + unsigned base_width; // Nominal video width of game. + unsigned base_height; // Nominal video height of game. + unsigned max_width; // Maximum possible width of game. + unsigned max_height; // Maximum possible height of game. + + float aspect_ratio; // Nominal aspect ratio of game. If aspect_ratio is <= 0.0, + // an aspect ratio of base_width / base_height is assumed. + // A frontend could override this setting if desired. +}; + +struct retro_system_timing +{ + double fps; // FPS of video content. + double sample_rate; // Sampling rate of audio. +}; + +struct retro_system_av_info +{ + struct retro_game_geometry geometry; + struct retro_system_timing timing; +}; + +struct retro_variable +{ + const char *key; // Variable to query in RETRO_ENVIRONMENT_GET_VARIABLE. + // If NULL, obtains the complete environment string if more complex parsing is necessary. + // The environment string is formatted as key-value pairs delimited by semicolons as so: + // "key1=value1;key2=value2;..." + const char *value; // Value to be obtained. If key does not exist, it is set to NULL. +}; + +struct retro_game_info +{ + const char *path; // Path to game, UTF-8 encoded. Usually used as a reference. + // May be NULL if rom was loaded from stdin or similar. + // retro_system_info::need_fullpath guaranteed that this path is valid. + const void *data; // Memory buffer of loaded game. Will be NULL if need_fullpath was set. + size_t size; // Size of memory buffer. + const char *meta; // String of implementation specific meta-data. +}; + +// Callbacks +// +// Environment callback. Gives implementations a way of performing uncommon tasks. Extensible. +typedef bool (*retro_environment_t)(unsigned cmd, void *data); + +// Render a frame. Pixel format is 15-bit 0RGB1555 native endian unless changed (see RETRO_ENVIRONMENT_SET_PIXEL_FORMAT). +// Width and height specify dimensions of buffer. +// Pitch specifices length in bytes between two lines in buffer. +// For performance reasons, it is highly recommended to have a frame that is packed in memory, i.e. pitch == width * byte_per_pixel. +// Certain graphic APIs, such as OpenGL ES, do not like textures that are not packed in memory. +typedef void (*retro_video_refresh_t)(const void *data, unsigned width, unsigned height, size_t pitch); + +// Renders a single audio frame. Should only be used if implementation generates a single sample at a time. +// Format is signed 16-bit native endian. +typedef void (*retro_audio_sample_t)(int16_t left, int16_t right); +// Renders multiple audio frames in one go. One frame is defined as a sample of left and right channels, interleaved. +// I.e. int16_t buf[4] = { l, r, l, r }; would be 2 frames. +// Only one of the audio callbacks must ever be used. +typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data, size_t frames); + +// Polls input. +typedef void (*retro_input_poll_t)(void); +// Queries for input for player 'port'. device will be masked with RETRO_DEVICE_MASK. +// Specialization of devices such as RETRO_DEVICE_JOYPAD_MULTITAP that have been set with retro_set_controller_port_device() +// will still use the higher level RETRO_DEVICE_JOYPAD to request input. +typedef int16_t (*retro_input_state_t)(unsigned port, unsigned device, unsigned index, unsigned id); + +// Sets callbacks. retro_set_environment() is guaranteed to be called before retro_init(). +// The rest of the set_* functions are guaranteed to have been called before the first call to retro_run() is made. +void retro_set_environment(retro_environment_t); +void retro_set_video_refresh(retro_video_refresh_t); +void retro_set_audio_sample(retro_audio_sample_t); +void retro_set_audio_sample_batch(retro_audio_sample_batch_t); +void retro_set_input_poll(retro_input_poll_t); +void retro_set_input_state(retro_input_state_t); + +// Library global initialization/deinitialization. +void retro_init(void); +void retro_deinit(void); + +// Must return RETRO_API_VERSION. Used to validate ABI compatibility when the API is revised. +unsigned retro_api_version(void); + +// Gets statically known system info. Pointers provided in *info must be statically allocated. +// Can be called at any time, even before retro_init(). +void retro_get_system_info(struct retro_system_info *info); + +// Gets information about system audio/video timings and geometry. +// Can be called only after retro_load_game() has successfully completed. +// NOTE: The implementation of this function might not initialize every variable if needed. +// E.g. geom.aspect_ratio might not be initialized if core doesn't desire a particular aspect ratio. +void retro_get_system_av_info(struct retro_system_av_info *info); + +// Sets device to be used for player 'port'. +void retro_set_controller_port_device(unsigned port, unsigned device); + +// Resets the current game. +void retro_reset(void); + +// Runs the game for one video frame. +// During retro_run(), input_poll callback must be called at least once. +// +// If a frame is not rendered for reasons where a game "dropped" a frame, +// this still counts as a frame, and retro_run() should explicitly dupe a frame if GET_CAN_DUPE returns true. +// In this case, the video callback can take a NULL argument for data. +void retro_run(void); + +// Returns the amount of data the implementation requires to serialize internal state (save states). +// Beetween calls to retro_load_game() and retro_unload_game(), the returned size is never allowed to be larger than a previous returned value, to +// ensure that the frontend can allocate a save state buffer once. +size_t retro_serialize_size(void); + +// Serializes internal state. If failed, or size is lower than retro_serialize_size(), it should return false, true otherwise. +bool retro_serialize(void *data, size_t size); +bool retro_unserialize(const void *data, size_t size); + +void retro_cheat_reset(void); +void retro_cheat_set(unsigned index, bool enabled, const char *code); + +// Loads a game. +bool retro_load_game(const struct retro_game_info *game); + +// Loads a "special" kind of game. Should not be used except in extreme cases. +bool retro_load_game_special( + unsigned game_type, + const struct retro_game_info *info, size_t num_info +); + +// Unloads a currently loaded game. +void retro_unload_game(void); + +// Gets region of game. +unsigned retro_get_region(void); + +// Gets region of memory. +void *retro_get_memory_data(unsigned id); +size_t retro_get_memory_size(unsigned id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/genplus-gx/libretro/link.T b/genplus-gx/libretro/link.T new file mode 100644 index 0000000000..6c94c67a5c --- /dev/null +++ b/genplus-gx/libretro/link.T @@ -0,0 +1,5 @@ +{ + global: retro_*; + local: *; +}; + diff --git a/genplus-gx/libretro/msvc/msvc-2003-xbox1.bat b/genplus-gx/libretro/msvc/msvc-2003-xbox1.bat new file mode 100644 index 0000000000..382269ea67 --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2003-xbox1.bat @@ -0,0 +1,47 @@ +@SET VSINSTALLDIR=C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE +@SET VCINSTALLDIR=C:\Program Files\Microsoft Visual Studio .NET 2003 +@SET FrameworkDir=C:\WINDOWS\Microsoft.NET\Framework +@SET FrameworkVersion=v1.1.4322 +@SET FrameworkSDKDir=C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1 +@rem Root of Visual Studio common files. + +@if "%VSINSTALLDIR%"=="" goto Usage +@if "%VCINSTALLDIR%"=="" set VCINSTALLDIR=%VSINSTALLDIR% + +@rem +@rem Root of Visual Studio ide installed files. +@rem +@set DevEnvDir=%VSINSTALLDIR% + +@rem +@rem Root of Visual C++ installed files. +@rem +@set MSVCDir=%VCINSTALLDIR%\VC7 + +@rem +@echo Setting environment for using Microsoft Visual Studio .NET 2003 tools. +@echo (If you have another version of Visual Studio or Visual C++ installed and wish +@echo to use its tools from the command line, run vcvars32.bat for that version.) +@rem + +@REM %VCINSTALLDIR%\Common7\Tools dir is added only for real setup. + +@set PATH=%DevEnvDir%;%MSVCDir%\BIN;%VCINSTALLDIR%\Common7\Tools;%VCINSTALLDIR%\Common7\Tools\bin\prerelease;%VCINSTALLDIR%\Common7\Tools\bin;%FrameworkSDKDir%\bin;%FrameworkDir%\%FrameworkVersion%;%PATH%; +@set INCLUDE=%MSVCDir%\ATLMFC\INCLUDE;%MSVCDir%\INCLUDE;%FrameworkSDKDir%\include;%INCLUDE%;%XDK%\xbox\include +@set LIB=%MSVCDir%\ATLMFC\LIB;%MSVCDir%\LIB;%MSVCDir%\PlatformSDK\lib;%XDK%\lib;%XDK%\xbox\lib;%LIB% + +@goto end + +:Usage + +@echo. VSINSTALLDIR variable is not set. +@echo. +@echo SYNTAX: %0 + +@goto end + +:end + +devenv /clean Release_LTCG msvc-2003-xbox1.sln +devenv /build Release_LTCG msvc-2003-xbox1.sln +exit diff --git a/genplus-gx/libretro/msvc/msvc-2003-xbox1.sln b/genplus-gx/libretro/msvc/msvc-2003-xbox1.sln new file mode 100644 index 0000000000..c463b7ed83 --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2003-xbox1.sln @@ -0,0 +1,30 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msvc-2003-xbox1", "msvc-2003-xbox1/msvc-2003-xbox1.vcproj", "{C0C3EF9B-2D9B-44D1-A83F-3617D8BA3421}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Profile = Profile + Profile_FastCap = Profile_FastCap + Release = Release + Release_LTCG = Release_LTCG + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {C0C3EF9B-2D9B-44D1-A83F-3617D8BA3421}.Debug.ActiveCfg = Debug|Xbox + {C0C3EF9B-2D9B-44D1-A83F-3617D8BA3421}.Debug.Build.0 = Debug|Xbox + {C0C3EF9B-2D9B-44D1-A83F-3617D8BA3421}.Profile.ActiveCfg = Profile|Xbox + {C0C3EF9B-2D9B-44D1-A83F-3617D8BA3421}.Profile.Build.0 = Profile|Xbox + {C0C3EF9B-2D9B-44D1-A83F-3617D8BA3421}.Profile_FastCap.ActiveCfg = Profile_FastCap|Xbox + {C0C3EF9B-2D9B-44D1-A83F-3617D8BA3421}.Profile_FastCap.Build.0 = Profile_FastCap|Xbox + {C0C3EF9B-2D9B-44D1-A83F-3617D8BA3421}.Release.ActiveCfg = Release|Xbox + {C0C3EF9B-2D9B-44D1-A83F-3617D8BA3421}.Release.Build.0 = Release|Xbox + {C0C3EF9B-2D9B-44D1-A83F-3617D8BA3421}.Release_LTCG.ActiveCfg = Release_LTCG|Xbox + {C0C3EF9B-2D9B-44D1-A83F-3617D8BA3421}.Release_LTCG.Build.0 = Release_LTCG|Xbox + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/genplus-gx/libretro/msvc/msvc-2003-xbox1/msvc-2003-xbox1.vcproj b/genplus-gx/libretro/msvc/msvc-2003-xbox1/msvc-2003-xbox1.vcproj new file mode 100644 index 0000000000..aaf879cc34 --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2003-xbox1/msvc-2003-xbox1.vcproj @@ -0,0 +1,543 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/genplus-gx/libretro/msvc/msvc-2003-xbox1/stdint.h b/genplus-gx/libretro/msvc/msvc-2003-xbox1/stdint.h new file mode 100644 index 0000000000..eb93fbc61b --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2003-xbox1/stdint.h @@ -0,0 +1,249 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef __RARCH_STDINT_H +#define __RARCH_STDINT_H + +#if _MSC_VER && (_MSC_VER < 1600) +//pre-MSVC 2010 needs an implementation of stdint.h + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + +#else +//sanity for everything else +#include +#endif + +#endif diff --git a/genplus-gx/libretro/msvc/msvc-2010-360.bat b/genplus-gx/libretro/msvc/msvc-2010-360.bat new file mode 100644 index 0000000000..6ddb7de4d0 --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2010-360.bat @@ -0,0 +1,124 @@ +@echo off + +@echo Setting environment for using Microsoft Visual Studio 2010 x86 tools. + +@call :GetVSCommonToolsDir +@if "%VS100COMNTOOLS%"=="" goto error_no_VS100COMNTOOLSDIR + +@call "%VS100COMNTOOLS%VCVarsQueryRegistry.bat" 32bit No64bit + +@if "%VSINSTALLDIR%"=="" goto error_no_VSINSTALLDIR +@if "%FrameworkDir32%"=="" goto error_no_FrameworkDIR32 +@if "%FrameworkVersion32%"=="" goto error_no_FrameworkVer32 +@if "%Framework35Version%"=="" goto error_no_Framework35Version + +@set FrameworkDir=%FrameworkDir32% +@set FrameworkVersion=%FrameworkVersion32% + +@if not "%WindowsSdkDir%" == "" ( + @set "PATH=%WindowsSdkDir%bin\NETFX 4.0 Tools;%WindowsSdkDir%bin;%PATH%" + @set "INCLUDE=%WindowsSdkDir%include;%INCLUDE%" + @set "LIB=%WindowsSdkDir%lib;%LIB%" +) + +@rem +@rem Root of Visual Studio IDE installed files. +@rem +@set DevEnvDir=%VSINSTALLDIR%Common7\IDE\ + +@rem PATH +@rem ---- +@if exist "%VSINSTALLDIR%Team Tools\Performance Tools" ( + @set "PATH=%VSINSTALLDIR%Team Tools\Performance Tools;%PATH%" +) +@if exist "%ProgramFiles%\HTML Help Workshop" set PATH=%ProgramFiles%\HTML Help Workshop;%PATH% +@if exist "%ProgramFiles(x86)%\HTML Help Workshop" set PATH=%ProgramFiles(x86)%\HTML Help Workshop;%PATH% +@if exist "%VCINSTALLDIR%VCPackages" set PATH=%VCINSTALLDIR%VCPackages;%PATH% +@set PATH=%FrameworkDir%%Framework35Version%;%PATH% +@set PATH=%FrameworkDir%%FrameworkVersion%;%PATH% +@set PATH=%VSINSTALLDIR%Common7\Tools;%PATH% +@if exist "%VCINSTALLDIR%BIN" set PATH=%VCINSTALLDIR%BIN;%PATH% +@set PATH=%DevEnvDir%;%PATH% + +@if exist "%VSINSTALLDIR%VSTSDB\Deploy" ( + @set "PATH=%VSINSTALLDIR%VSTSDB\Deploy;%PATH%" +) + +@if not "%FSHARPINSTALLDIR%" == "" ( + @set "PATH=%FSHARPINSTALLDIR%;%PATH%" +) + +@rem INCLUDE +@rem ------- +@if exist "%VCINSTALLDIR%ATLMFC\INCLUDE" set INCLUDE=%VCINSTALLDIR%ATLMFC\INCLUDE;%INCLUDE% +@if exist "%VCINSTALLDIR%INCLUDE" set INCLUDE=%VCINSTALLDIR%INCLUDE;%INCLUDE% + +@rem LIB +@rem --- +@if exist "%VCINSTALLDIR%ATLMFC\LIB" set LIB=%VCINSTALLDIR%ATLMFC\LIB;%LIB% +@if exist "%VCINSTALLDIR%LIB" set LIB=%VCINSTALLDIR%LIB;%LIB% + +@rem LIBPATH +@rem ------- +@if exist "%VCINSTALLDIR%ATLMFC\LIB" set LIBPATH=%VCINSTALLDIR%ATLMFC\LIB;%LIBPATH% +@if exist "%VCINSTALLDIR%LIB" set LIBPATH=%VCINSTALLDIR%LIB;%LIBPATH% +@set LIBPATH=%FrameworkDir%%Framework35Version%;%LIBPATH% +@set LIBPATH=%FrameworkDir%%FrameworkVersion%;%LIBPATH% + +@goto end + +@REM ----------------------------------------------------------------------- +:GetVSCommonToolsDir +@set VS100COMNTOOLS= +@call :GetVSCommonToolsDirHelper32 HKLM > nul 2>&1 +@if errorlevel 1 call :GetVSCommonToolsDirHelper32 HKCU > nul 2>&1 +@if errorlevel 1 call :GetVSCommonToolsDirHelper64 HKLM > nul 2>&1 +@if errorlevel 1 call :GetVSCommonToolsDirHelper64 HKCU > nul 2>&1 +@exit /B 0 + +:GetVSCommonToolsDirHelper32 +@for /F "tokens=1,2*" %%i in ('reg query "%1\SOFTWARE\Microsoft\VisualStudio\SxS\VS7" /v "10.0"') DO ( + @if "%%i"=="10.0" ( + @SET "VS100COMNTOOLS=%%k" + ) +) +@if "%VS100COMNTOOLS%"=="" exit /B 1 +@SET "VS100COMNTOOLS=%VS100COMNTOOLS%Common7\Tools\" +@exit /B 0 + +:GetVSCommonToolsDirHelper64 +@for /F "tokens=1,2*" %%i in ('reg query "%1\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\SxS\VS7" /v "10.0"') DO ( + @if "%%i"=="10.0" ( + @SET "VS100COMNTOOLS=%%k" + ) +) +@if "%VS100COMNTOOLS%"=="" exit /B 1 +@SET "VS100COMNTOOLS=%VS100COMNTOOLS%Common7\Tools\" +@exit /B 0 + +@REM ----------------------------------------------------------------------- +:error_no_VS100COMNTOOLSDIR +@echo ERROR: Cannot determine the location of the VS Common Tools folder. +@goto end + +:error_no_VSINSTALLDIR +@echo ERROR: Cannot determine the location of the VS installation. +@goto end + +:error_no_FrameworkDIR32 +@echo ERROR: Cannot determine the location of the .NET Framework 32bit installation. +@goto end + +:error_no_FrameworkVer32 +@echo ERROR: Cannot determine the version of the .NET Framework 32bit installation. +@goto end + +:error_no_Framework35Version +@echo ERROR: Cannot determine the .NET Framework 3.5 version. +@goto end + +:end + +msbuild msvc-2010-360.sln /p:Configuration=Release_LTCG /target:clean +msbuild msvc-2010-360.sln /p:Configuration=Release_LTCG +exit diff --git a/genplus-gx/libretro/msvc/msvc-2010-360.sln b/genplus-gx/libretro/msvc/msvc-2010-360.sln new file mode 100644 index 0000000000..449143d4c4 --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2010-360.sln @@ -0,0 +1,38 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genesis-next-msvc-2010-360", "msvc-2010-360\msvc-2010-360.vcxproj", "{00CE82EC-E948-4BB6-B726-23BF1571B05A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + CodeAnalysis|Xbox 360 = CodeAnalysis|Xbox 360 + Debug|Xbox 360 = Debug|Xbox 360 + Profile_FastCap|Xbox 360 = Profile_FastCap|Xbox 360 + Profile|Xbox 360 = Profile|Xbox 360 + Release_LTCG|Xbox 360 = Release_LTCG|Xbox 360 + Release|Xbox 360 = Release|Xbox 360 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.CodeAnalysis|Xbox 360.ActiveCfg = CodeAnalysis|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.CodeAnalysis|Xbox 360.Build.0 = CodeAnalysis|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.CodeAnalysis|Xbox 360.Deploy.0 = CodeAnalysis|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Debug|Xbox 360.ActiveCfg = Debug|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Debug|Xbox 360.Build.0 = Debug|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Debug|Xbox 360.Deploy.0 = Debug|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Profile_FastCap|Xbox 360.ActiveCfg = Profile_FastCap|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Profile_FastCap|Xbox 360.Build.0 = Profile_FastCap|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Profile_FastCap|Xbox 360.Deploy.0 = Profile_FastCap|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Profile|Xbox 360.ActiveCfg = Profile|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Profile|Xbox 360.Build.0 = Profile|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Profile|Xbox 360.Deploy.0 = Profile|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Release_LTCG|Xbox 360.ActiveCfg = Release_LTCG|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Release_LTCG|Xbox 360.Build.0 = Release_LTCG|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Release_LTCG|Xbox 360.Deploy.0 = Release_LTCG|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Release|Xbox 360.ActiveCfg = Release|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Release|Xbox 360.Build.0 = Release|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Release|Xbox 360.Deploy.0 = Release|Xbox 360 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/genplus-gx/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj b/genplus-gx/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj new file mode 100644 index 0000000000..324835b855 --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj @@ -0,0 +1,373 @@ + + + + + CodeAnalysis + Xbox 360 + + + Debug + Xbox 360 + + + Profile + Xbox 360 + + + Profile_FastCap + Xbox 360 + + + Release + Xbox 360 + + + Release_LTCG + Xbox 360 + + + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + + + + + + + + + + + + + + + + + + + + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + + + + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + + + + + + + + + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + + {00CE82EC-E948-4BB6-B726-23BF1571B05A} + Xbox360Proj + genesis-next-msvc-2010-360 + + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + $(OutDir)genesis_plus_gx_libretro_xdk360$(TargetExt) + + + $(OutDir)genesis_plus_gx_libretro_xdk360$(TargetExt) + + + $(OutDir)genesis_plus_gx_libretro_xdk360$(TargetExt) + + + $(OutDir)genesis_plus_gx_libretro_xdk360$(TargetExt) + + + $(OutDir)genesis_plus_gx_libretro_xdk360$(TargetExt) + + + $(OutDir)genesis_plus_gx_libretro_xdk360$(TargetExt) + + + + NotUsing + Level3 + ProgramDatabase + Disabled + false + true + false + $(OutDir)$(ProjectName).pch + MultiThreadedDebug + _DEBUG;_XBOX;_XBOX360;_LIB;INLINE=static _inline;__attribute__=;__inline__=_inline;__extension__=;USE_16BPP_RENDERING;__LIBRETRO__;FRONTEND_SUPPORTS_RGB565;%(PreprocessorDefinitions) + Callcap + $(SolutionDir)\..\..\core;$(SolutionDir)\..\..\core\cd_hw;$(SolutionDir)\..\..\core\cart_hw;$(SolutionDir)\..\..\core\sound;$(SolutionDir)\..\..\core\z80;$(SolutionDir)\..\..\core\m68k;$(SolutionDir)\..\..\core\input_hw;$(SolutionDir)\..\..\core\cart_hw\svp;$(SolutionDir)\..\..\core\ntsc;$(SolutionDir)\..\;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) + CompileAsC + + + true + + + + + NotUsing + Level4 + ProgramDatabase + Disabled + false + true + AnalyzeOnly + false + $(OutDir)$(ProjectName).pch + MultiThreadedDebug + _DEBUG;_XBOX;_XBOX360;_LIB;%(PreprocessorDefinitions);INLINE=static _inline;__attribute__=;__inline__=_inline;__extension__=;USE_16BPP_RENDERING;__LIBRETRO__;FRONTEND_SUPPORTS_RGB565 + Callcap + $(SolutionDir)\..\..\core;$(SolutionDir)\..\..\core\cd_hw;$(SolutionDir)\..\..\core\cart_hw;$(SolutionDir)\..\..\core\sound;$(SolutionDir)\..\..\core\z80;$(SolutionDir)\..\..\core\m68k;$(SolutionDir)\..\..\core\input_hw;$(SolutionDir)\..\..\core\cart_hw\svp;$(SolutionDir)\..\..\core\ntsc;$(SolutionDir)\..\;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) + CompileAsC + + + true + + + + + Level3 + NotUsing + Full + true + false + true + ProgramDatabase + Size + false + $(OutDir)$(ProjectName).pch + MultiThreaded + NDEBUG;_XBOX;_XBOX360;PROFILE;_LIB;__LIBRETRO__;USE_16BPP_RENDERING;INLINE=static _inline;FRONTEND_SUPPORTS_RGB565;%(PreprocessorDefinitions) + Callcap + $(SolutionDir)\..\..\core;$(SolutionDir)\..\..\core\cd_hw;$(SolutionDir)\..\..\core\cart_hw;$(SolutionDir)\..\..\core\sound;$(SolutionDir)\..\..\core\z80;$(SolutionDir)\..\..\core\m68k;$(SolutionDir)\..\..\core\input_hw;$(SolutionDir)\..\..\core\cart_hw\svp;$(SolutionDir)\..\..\core\ntsc;$(SolutionDir)\..\;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) + CompileAsC + + + true + false + xapilib.lib;%(IgnoreSpecificDefaultLibraries) + true + + + + + Level3 + NotUsing + Full + true + false + true + ProgramDatabase + Fastcap + Size + false + $(OutDir)$(ProjectName).pch + MultiThreaded + NDEBUG;_XBOX;_XBOX360;PROFILE;FASTCAP;_LIB;__LIBRETRO__;USE_16BPP_RENDERING;INLINE=static _inline;FRONTEND_SUPPORTS_RGB565;%(PreprocessorDefinitions) + $(SolutionDir)\..\..\core;$(SolutionDir)\..\..\core\cd_hw;$(SolutionDir)\..\..\core\cart_hw;$(SolutionDir)\..\..\core\sound;$(SolutionDir)\..\..\core\z80;$(SolutionDir)\..\..\core\m68k;$(SolutionDir)\..\..\core\input_hw;$(SolutionDir)\..\..\core\cart_hw\svp;$(SolutionDir)\..\..\core\ntsc;$(SolutionDir)\..\;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) + CompileAsC + + + true + false + true + + + + + Level3 + NotUsing + Full + true + true + ProgramDatabase + Size + false + false + $(OutDir)$(ProjectName).pch + MultiThreaded + NDEBUG;_XBOX;_XBOX360;_LIB;INLINE=static _inline;__inline__=_inline;__extension__=;USE_16BPP_RENDERING;__LIBRETRO__;FRONTEND_SUPPORTS_RGB565;%(PreprocessorDefinitions) + $(SolutionDir)\..\..\core;$(SolutionDir)\..\..\core\cd_hw;$(SolutionDir)\..\..\core\cart_hw;$(SolutionDir)\..\..\core\sound;$(SolutionDir)\..\..\core\z80;$(SolutionDir)\..\..\core\m68k;$(SolutionDir)\..\..\core\input_hw;$(SolutionDir)\..\..\core\cart_hw\svp;$(SolutionDir)\..\..\core\ntsc;$(SolutionDir)\..\;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) + CompileAsC + + + true + true + true + + + + + Level3 + NotUsing + Full + true + true + ProgramDatabase + Size + false + false + $(OutDir)$(ProjectName).pch + MultiThreaded + NDEBUG;_XBOX;_XBOX360;LTCG;_LIB;INLINE=static _inline;__inline__=_inline;__extension__=;USE_16BPP_RENDERING;__LIBRETRO__;FRONTEND_SUPPORTS_RGB565;%(PreprocessorDefinitions) + $(SolutionDir)\..\..\core;$(SolutionDir)\..\..\core\cd_hw;$(SolutionDir)\..\..\core\cart_hw;$(SolutionDir)\..\..\core\sound;$(SolutionDir)\..\..\core\z80;$(SolutionDir)\..\..\core\m68k;$(SolutionDir)\..\..\core\input_hw;$(SolutionDir)\..\..\core\cart_hw\svp;$(SolutionDir)\..\..\core\ntsc;$(SolutionDir)\..\;$(SolutionDir)\..\..\;%(AdditionalIncludeDirectories) + CompileAsC + + + true + true + true + + + + + + diff --git a/genplus-gx/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj.filters b/genplus-gx/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj.filters new file mode 100644 index 0000000000..5fa17a2e40 --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj.filters @@ -0,0 +1,186 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {c0268b8d-1c7d-44d5-ae67-e3e365c991b7} + + + {c3d17076-e795-431e-b50f-7606c81367b9} + + + {5351583e-dbd9-4060-8497-6ddfd31e3666} + + + {943f2af4-23b4-43eb-b9cd-91cc7af172c5} + + + {ff45bed3-12a9-437d-ac34-7e83518ba624} + + + {f0c37c57-d905-4002-a129-5b9ffc907c05} + + + {2f0a4c83-ad74-4742-baef-35fafdca0e67} + + + {c90aed8d-25e3-439e-acec-f66acc8b4c0d} + + + {d8d4356b-c678-422e-aa12-9f52ba60fdbc} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\z80 + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\ntsc + + + Source Files\ntsc + + + Source Files\m68k + + + Source Files\m68k + + + Source Files\libretro + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw\svp + + + Source Files\cart_hw\svp + + + Source Files\cd_hw + + + Source Files\cd_hw + + + Source Files\cd_hw + + + Source Files\cd_hw + + + Source Files\cd_hw + + + Source Files\cd_hw + + + Source Files\sound + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + diff --git a/genplus-gx/libretro/msvc/msvc-2010.sln b/genplus-gx/libretro/msvc/msvc-2010.sln new file mode 100644 index 0000000000..0c72fd538b --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2010.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msvc-2010", "msvc-2010/msvc-2010.vcxproj", "{29DF2EE7-2930-4BD3-8AC5-81A2534ACC99}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {29DF2EE7-2930-4BD3-8AC5-81A2534ACC99}.Debug|Win32.ActiveCfg = Debug|Win32 + {29DF2EE7-2930-4BD3-8AC5-81A2534ACC99}.Debug|Win32.Build.0 = Debug|Win32 + {29DF2EE7-2930-4BD3-8AC5-81A2534ACC99}.Release|Win32.ActiveCfg = Release|Win32 + {29DF2EE7-2930-4BD3-8AC5-81A2534ACC99}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/genplus-gx/libretro/msvc/msvc-2010/libretro.def b/genplus-gx/libretro/msvc/msvc-2010/libretro.def new file mode 100644 index 0000000000..364b2ce4ce --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2010/libretro.def @@ -0,0 +1,27 @@ +LIBRARY "libretro-prboom msvc2010" +EXPORTS +retro_set_environment +retro_set_video_refresh +retro_set_audio_sample +retro_set_audio_sample_batch +retro_set_input_poll +retro_set_input_state +retro_init +retro_deinit +retro_api_version +retro_get_system_info +retro_get_system_av_info +retro_set_controller_port_device +retro_reset +retro_run +retro_serialize_size +retro_serialize +retro_unserialize +retro_cheat_reset +retro_cheat_set +retro_load_game +retro_load_game_special +retro_unload_game +retro_get_region +retro_get_memory_data +retro_get_memory_size diff --git a/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj b/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj new file mode 100644 index 0000000000..e1fdf15d94 --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {29DF2EE7-2930-4BD3-8AC5-81A2534ACC99} + Win32Proj + msvc2010 + genesis-next-msvc-2010 + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + true + libgenplusgx + + + false + libgenplusgx + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MSVC2010_EXPORTS;_CRT_SECURE_NO_WARNINGS;INLINE=static _inline;__inline__=_inline;__extension__=;LSB_FIRST;USE_32BPP_RENDERING;FRONTEND_SUPPORTS_RGB565;%(PreprocessorDefinitions) + $(SolutionDir)/../../core;$(SolutionDir)/../../utils/zlib;$(SolutionDir)/../../core/cart_hw/svp;$(SolutionDir)/../../libretro;$(SolutionDir)/../../core/m68k;$(SolutionDir)/../../core/z80;$(SolutionDir)/../../core/input_hw;$(SolutionDir)/../../core/cart_hw;$(SolutionDir)/../../core/sound;$(SolutionDir)/../../core/ntsc;$(SolutionDir)/../../core/cd_hw;%(AdditionalIncludeDirectories) + + + Windows + true + + + + + copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\..\..\..\output\dll\$(TargetFileName) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MSVC2010_EXPORTS;_CRT_SECURE_NO_WARNINGS;INLINE=static _inline;__inline__=_inline;__extension__=;LSB_FIRST;USE_32BPP_RENDERING;FRONTEND_SUPPORTS_RGB565;%(PreprocessorDefinitions) + $(SolutionDir)/../../core;$(SolutionDir)/../../utils/zlib;$(SolutionDir)/../../core/cart_hw/svp;$(SolutionDir)/../../libretro;$(SolutionDir)/../../core/m68k;$(SolutionDir)/../../core/z80;$(SolutionDir)/../../core/input_hw;$(SolutionDir)/../../core/cart_hw;$(SolutionDir)/../../core/sound;$(SolutionDir)/../../core/ntsc;$(SolutionDir)/../../core/cd_hw;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + + copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\..\..\..\output\dll\$(TargetFileName) + + + + + + \ No newline at end of file diff --git a/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters b/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters new file mode 100644 index 0000000000..de5c4cfc9a --- /dev/null +++ b/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters @@ -0,0 +1,196 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {e0f9ca3b-df0f-4cf9-bde1-9fa3c945b0df} + + + {0605ef1a-d898-494c-a898-8f06000646ae} + + + {8b373848-96f7-4410-a466-5d7cb6866b0f} + + + {ea37a461-94f4-40e3-91a8-2b254b94f547} + + + {becebb08-7987-4fe3-8ee0-dd47889d4996} + + + {e66cf784-cb76-4a70-a2e0-327a3b4c96eb} + + + {39a1110f-2062-4e3c-9f43-aca63cc20cda} + + + {95e90e29-1915-4f70-b6e0-50b9dace48cf} + + + {eba4b43d-dbd8-4170-9853-e3234db6dfc0} + + + {917c9b25-741c-4702-97c5-c10ecd033b20} + + + + + Source Files\cart_hw\svp + + + Source Files\cart_hw\svp + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\m68k + + + Source Files\m68k + + + Source Files\ntsc + + + Source Files\ntsc + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\z80 + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\cd_hw + + + Source Files\cd_hw + + + Source Files\cd_hw + + + Source Files\cd_hw + + + Source Files\cd_hw + + + Source Files\cd_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\sound + + + Source Files\cinterface + + + Source Files\libretro + + + \ No newline at end of file diff --git a/genplus-gx/libretro/osd.h b/genplus-gx/libretro/osd.h new file mode 100644 index 0000000000..fad583084b --- /dev/null +++ b/genplus-gx/libretro/osd.h @@ -0,0 +1,84 @@ +#ifndef _OSD_H +#define _OSD_H + +#ifdef _MSC_VER +#include +typedef unsigned char bool; +#define strncasecmp _strnicmp +#endif + +#include +#include +#include + +#define MAX_INPUTS 8 +#define MAX_KEYS 8 +#define MAXPATHLEN 1024 + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef M_PI +#define M_PI 3.1415926535897932385 +#endif + +typedef struct +{ + int8 device; + uint8 port; + uint8 padtype; +} t_input_config; + +struct +{ + char version[16]; + uint8 hq_fm; + uint8 filter; + uint8 psgBoostNoise; + uint8 dac_bits; + uint8 ym2413; + uint8 mono; + int16 psg_preamp; + int16 fm_preamp; + int16 lp_range; + int16 low_freq; + int16 high_freq; + int16 lg; + int16 mg; + int16 hg; + uint8 system; + uint8 region_detect; + uint8 master_clock; + uint8 vdp_mode; + uint8 force_dtack; + uint8 addr_error; + uint8 bios; + uint8 lock_on; + uint8 overscan; + uint8 ntsc; + uint8 gg_extra; + uint8 render; + t_input_config input[MAX_INPUTS]; +} config; + +extern char GG_ROM[256]; +extern char AR_ROM[256]; +extern char SK_ROM[256]; +extern char SK_UPMEM[256]; +extern char GG_BIOS[256]; +extern char CD_BIOS_EU[256]; +extern char CD_BIOS_US[256]; +extern char CD_BIOS_JP[256]; +extern char MS_BIOS_US[256]; +extern char MS_BIOS_EU[256]; +extern char MS_BIOS_JP[256]; + +void osd_input_update(void); +int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension); + +#endif /* _OSD_H */ diff --git a/genplus-gx/libretro/qnx/playbook/.cproject b/genplus-gx/libretro/qnx/playbook/.cproject new file mode 100644 index 0000000000..d00d641a5b --- /dev/null +++ b/genplus-gx/libretro/qnx/playbook/.cproject @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/genplus-gx/libretro/qnx/playbook/.project b/genplus-gx/libretro/qnx/playbook/.project new file mode 100644 index 0000000000..9d506c56ea --- /dev/null +++ b/genplus-gx/libretro/qnx/playbook/.project @@ -0,0 +1,85 @@ + + + Genesis-Plus-GX + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + -C../../.. -fMakefile.libretro platform=qnx + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + false + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + com.qnx.tools.ide.bbt.core.bbtnature + org.eclipse.cdt.core.ccnature + + diff --git a/genplus-gx/libretro/scrc32.c b/genplus-gx/libretro/scrc32.c new file mode 100644 index 0000000000..dc0a137d38 --- /dev/null +++ b/genplus-gx/libretro/scrc32.c @@ -0,0 +1,79 @@ +#ifndef _S_CRC32_H +#define _S_CRC32_H + +static const unsigned long crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +#define DO1_CRC32(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2_CRC32(buf) DO1_CRC32(buf); DO1_CRC32(buf); +#define DO4_CRC32(buf) DO2_CRC32(buf); DO2_CRC32(buf); +#define DO8_CRC32(buf) DO4_CRC32(buf); DO4_CRC32(buf); + +unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len) +{ + if (buf == 0) return 0L; + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8_CRC32(buf); + len -= 8; + } + if (len) do { + DO1_CRC32(buf); + } while (--len); + return crc ^ 0xffffffffL; +} + +#endif diff --git a/genplus-gx/libretro/scrc32.h b/genplus-gx/libretro/scrc32.h new file mode 100644 index 0000000000..638dddc431 --- /dev/null +++ b/genplus-gx/libretro/scrc32.h @@ -0,0 +1,6 @@ +#ifndef _S_CRC32_H +#define _S_CRC32_H + +unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len); + +#endif diff --git a/genplus-gx/sdl/CHANGELOG.txt b/genplus-gx/sdl/CHANGELOG.txt new file mode 100644 index 0000000000..7d7d2cc780 --- /dev/null +++ b/genplus-gx/sdl/CHANGELOG.txt @@ -0,0 +1,694 @@ +-------------------- +Genesis Plus History +-------------------- + +All recent changes were backported from the GX version (Gamecube/Wii port), maintained by Eke-Eke. +Please look at http://code.google.com/p/genplus-gx/ for more infos. + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.7.4 (21/06/2013) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/SCD] +--------------- +* fixed access to read-only registers on Main-CPU side ("Batman Returns" platform level freeze) +* fixed & improved emulation of PRG-RAM write protection register ("Lunar Eternal Blue" japanese version freeze) +* improved SUB & MAIN-CPU synchronization ("Dracula Unleashed" freeze when using US Model 2 BIOS) +* improved CPU polling detection +* improved CDD emulation & added CD drive access time for SEEK command ("Panic!/Switch" intro missing scene) +* added missing reinitialization of MAIN-CPU PRG-RAM bank on reset +* added .OGG audio tracks support through LIBTREMOR + +[Core/Sound] +--------------- +* fixed YM2612 configurable DAC depth emulation +* improved Low-Pass filter +* added optional "MONO" output mode + +[Core/VDP] +--------------- +* fixed FIFO access timings when using invalid write code value ("Clue" menu) +* fixed DMA Copy with undocumented code value ("Fatal Labyrinth" end sequence) +* minor code fixes & optimizations + +[Core/CPU] +--------------- +* optimized 68k stack read/write functions +* fixed broken 68k address error emulation +* fixed 68k interrupt behavior (prevents interrupts from being executed multiple time when 68k is halted) +* fixed Z80 registers initial state, added proper initialization when using PBC (verified on real hardware by Charles McDonald) + +[Core/MD] +--------------- +* fixed SRAM incompatibilities between BIG ENDIAN & LITTLE ENDIAN platforms (note: this breaks old .srm files with LITTLE ENDIAN platform ports) +* added support for a few recently dumped unlicensed games +* added auto-detection of byte-swapped ROM files + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.7.3 (26/11/2012) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +no win32/SDL port changes + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.7.2 (24/11/2012) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/SCD] +--------------- +* added default TOC for Shadow of the Beast II (prevent hangs when audio tracks are missing) +* fixed CD-DA fader muting +* fixed PCM channels panning on reset +* fixed backup RAM file management when using disc swap with Mode 1 cartridge +* incremented CD drive read latency: fixes Space Adventure Cobra (freeze when opening coffin at 2nd morgue scene) +* improved CDD emulation accuracy: fixes Snatcher (freeze at the end of Act 2) & various CD player bugs +* improved MAIN-SUB memory map mirroring in SCD mode (verified on real hardware by Charles McDonald) +* implemented cycle-accurate "stopwatch" register emulation + +[Core/Sound] +--------------- +* fixed broken PSG noise frequency +* fixed incorrect Game Gear PSG stereo emulation +* implemented cycle-accurate Game Gear PSG stereo + +[Core/VDP] +--------------- +* fixed broken VDP DMA from SVP ROM latency (graphic errors in Virtua Racing) + +[Core/MD] +--------------- +* added Super Mario World 64 (unlicensed) cartridge hardware emulation + +[Core/Input] +--------------- +* added automatic detection for CD games with Justifier/Menacer support +* improved Justifier/Menacer emulation + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.7.1 (13/10/2012) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/SCD] +--------------- +* added support for CUE files +* added CD-DA tracks emulation (needs CUE+BIN or ISO+WAV images) +* added CD fader emulation +* added CDD "Fast FW" & "Fast RW" commands emulation +* improved CDD TOC emulation (random freezes in Sonic CD, Switch/Panic, Final Fight CD and probably many others) +* improved PCM chip synchronization with SUB-CPU (missing speeches in Willy Beamish) +* fixed PCM chip emulation (random hangs in Snatcher, missing sound effects in Switch/Panic, Final Fight CD, Wonderdog...) +* fixed Word-RAM memory mode on soft-reset (missing logo gfx effects) +* fixed SUB-CPU access to unused areas when using PC-relative instructions (Final Fight CD first boss random crash) +* fixed CPU idle loop detection on memory mode register access (Pugsy CD first boss slowdown) +* fixed Mode 1 emulation (cartridge boot mode) + +[Core/Sound] +--------------- +* replaced FIR resampler by Blip Buffer for FM resampling +* modified SN76489 core for use of Blip Buffer +* improved PSG & FM chips synchronization using Blip Buffer +* added Game Gear PSG stereo support +* fixed SG-1000 specific PSG noise +* fixed YM2612 LFO AM waveform (California Games surfing event) +* fixed YM2612 phase precision +* minor optimizations to YM2612 core + +[Core/Game Gear] +--------------- +* added support for CJ Elephant Fugitive (recently released by SMS Power) +* added Game Gear extended screen option + +[Core/Genesis] +--------------- +* added support for a few recently dumped (but unreleased) games + +[Core/General] +--------------- +* improved ROM & CD image file loading +* various code cleanup + + +--------------------------------------------------------------------------------------------------------- +Genesis Plus GX 1.7.0 (01/07/2012) (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/SCD] +--------------- +* added Mega CD / Sega CD hardware emulation (incl. Sub 68K, CDD, CDC, PCM, GFX rotation/scaling, etc) +* added .ISO & .BIN CD image file support +* added 512K backup cartridge RAM support +* added savestate support for CD games + +NOTES: +~~~~~~ +* to play CD games, original BIOS ROM files are required in /genplus/bios/ directory: unzip & rename them to bios_CD_U.bin, bios_CD_E.bin, bios_CD_J.bin +* CD audio tracks (CD-DA) are not supported (yet) + +[Core/CPU] +--------------- +* modified 68k core for Mega CD / Sega CD support +* optimized 68k core using prebuild const tables + +[Core/VDP] +--------------- +* improved DMA accuracy +* improved accuracy of nametables register & VSRAM writes during HBLANK: fixes "The Adventures of Batman & Robin" (graphical issues during 2nd Boss fight). +* added support for 8-bit VRAM writes with undocumented code value (verified on real hardware by Nemesis) + +[Core/Sound] +--------------- +* improved synchronization between SN76489 & YM2162 cores. +* improved accuracy of SN76489 core timings. + +[Core/MD] +--------------- +* added support for some recently dumped unlicensed games. +* improved emulation of 32k bankswitch hardware used by a few unlicensed games. +* fixed behavior of Z80 banked reads from 68k RAM (verified on real hardware). +* fixed support for 128K Pro Action Replay ROM. + +[Core/MS] +--------------- +* added support for all recent korean ROM dumps by SMS Power. +* added emulation of korean multi-game mapper (4-Pak All Action) +* added pseudo-random RAM pattern initialization on Mark-III and Japanese Master System (fixes "Alibaba and 40 Thieves" & "Block Hole") +* added port $3E emulation & internal BOOTROM support (Master System & Game Gear only). + +[Core/General] +--------------- +* added an option to set VDP mode (PAL/NTSC) independently from console region. +* added an option to select original system master clock frequency (PAL/NTSC/AUTO), emulation will run at selected frequency when VSYNC is disabled. +* fixed 68k context loading/saving (Sol Deace). +* fixed C89 incompatibilities for better portability. +* removed use of "long int" type for portability on 64-bit platforms. +* moved savestate zlib compression out of emulation core (for ports that don't use it). +* various optimizations. + +[Gamecube/Wii] +--------------- +* removed ROM load device selection from Load Menu: default ROM device must now be configured in menu settings. +* added specific load buttons, browsers & saved paths for each systems, this also fixes slowdowns caused by screenshot loading when browsing from slow devices. +* added support for left/right buttons as page up/down keys in ROM browsers +* added right analog stick as default "return to menu" key for Gamecube controllers +* added alternate remappable menu key combo for Gamecube controllers +* added an option to disable VSYNC (emulator is synced with audio hardware instead of video). +* added an option to boot system from "BIOS", with or without cartridge. +* added Master System & Game Gear "BIOS" support (files should be named bios_U.sms, bios_J.sms, bios_E.sms & bios.gg and copied to /genplus/bios directory). +* replaced "Hard Reset" button by a Soft Reset for systems having a Reset button (Mega Drive / Genesis & Master System) +* State & SRAM files are now only compressed when saving to Gamecube Memory Cards +* various fixes & cleanup. +* compiled with devkitPPC r26 & libogc 1.8.11. + +[Gamecube] +---------- +* improved progressive mode support when component cable is detected (hold B during startup to switch menu video mode configuration) + + +--------------------------------------------------------------------------------------------------------- +[07/08/2011] version 1.6.0 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/Sound] +--------------- +* added YM2413 emulation in Master System compatibility mode. +* fixed SN76489 noise boost initialization. +* minor YM2612 core optimizations. + +[Core/VDP] +--------------- +* added accurate emulation of SG-1000, Master System (315-5124, 315-5246) & Game Gear VDP. +* added support for all TMS9918 rendering modes. +* improved Mega Drive VDP timings accuracy in Master System Compatibility mode. +* fixed color palette initialization. +* fixed shifted sprites rendering in Mode 4. +* modified pixel rendering support (pixel depth is now forced at compilation time). + +[Core/CPU] +--------------- +* optimized 68k core (rewrote 68k interrupt handling, removed multiple CPU types support & unused code) for 5~8% speed improvment + +[Core/IO] +--------------- +* added accurate emulation of Master System (315-5216, 315-5237, 315-5297) & Game Gear I/O controllers. +* added Terebi Oekaki tablet emulation. +* improved Mouse emulation (fixes mouse support in Cannon Fodder). +* improved Justifier emulation (fixes gun support in Lethal Enforcers 2). +* improved 6-Buttons control pad emulation (fixes Duke Nukem 3D) +* modified lightgun emulation to use common key inputs for all devices. +* 2-buttons controller is now picked by default for Master System games. + +[Core/MD] +--------------- +* added copy-protection hardware emulation for some new dumped games (Tiny Toon Adventures 3, Mighty Morphin Power Rangers & The Battle of Red Cliffs). +* added Game Toshokan in EEPROM database (verified on real cartridge). +* fixed Micro Machines 2 - Turbo Tournament EEPROM size (verified on real cartridge). +* modified SRAM banswitch hardware emulation to be more compatible with some hacks. + +[Core/MS] +--------------- +* added Cyborg Z to Korean mapper database. + +[Core/GG] +--------------- +* added 93C46 EEPROM emulation (Majors Pro Baseball, World Series Baseball & World Series Baseball 95). + +[Core/General] +--------------- +* added support for .mdx ROM format. +* added Game Gear & SG-1000 ROM support. +* added accurate emulation of SG-1000, Master System (I, II) & Game Gear hardware models for 100% compatibility. +* updated to new Genesis Plus license (see http://cgfm2.emuviews.com/) +* removed DOS port +* various code cleanup. + + +--------------------------------------------------------------------------------------------------------- +[31/03/2011] version 1.5.0 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/VDP] +--------------- +* added support for Master System compatibility mode (Z80 ports access mode), incl. Mode 5 rendering. +* added Mode 4 rendering for both Genesis & Master System modes. +* added alternate BG planes rendering functions (should be faster on PPC architectures). + +[Core/IO] +--------------- +* added support for Master System compatibility mode (Z80 ports access mode). +* added Master System peripherals emulation (Control Pad, Paddle, Sports Pad & Light Phaser). +* added XE-1AP (analog controller) emulation. +* added Activator emulation. + +[Core/Extra] +--------------- +* added support for all known Master System cartridge mappers. +* added copy-protection hardware emulation for a few MD unlicensed games: fixes 777 Casino (crash when talking to bunny girls). +(NB: most of those unlicensed games seem to have been already patched by ROM dumpers, main purpose is documenting them) +* added support for Top Shooter arcade board controller. (A=Shoot, B=Bet, C/RIGHT=Coins, START=Start, hold UP on startup to enter service mode) +* improved King of Fighters 98 mapper emulation (registers address decoding is now 100% accurate) +* fixed Game Genie when several codes affect same ROM address. +* fixed EEPROM types for Brian Lara Cricket & NBA Jam TE (verified on real cartridges) + +[Core/General] +--------------- +* added Master System compatibility mode emulation (automatically enabled when loading ROM file with .sms extension). +* improved savestate stability & compatibility (support for old 1.4.x savestates is preserved) +* various code cleanup & comments. + + +--------------------------------------------------------------------------------------------------------- +[04/12/2010] version 1.4.1 (Eke-Eke) +--------------------------------------------------------------------------------------------------------- + +[Core/Sound] +--------------- +* implemented Blargg's blip buffer in SN76489 core (all channels are now lineary interpolated) + +[Core/VDP] +--------------- +* improved 2-cell vscroll emulation accuracy, as verified on real hardware (Gynoug, Cutie Suzuki no Ringside Angel, Formula One, Kawasaki Superbike Challenge) +* improved VBLANK flag accuracy, as observed on real hardware. +* improved DMA operations accuracy, writes are now performed on a scanline basis: fixes Gaiares (flickering title screen). +* improved DMA Fill timing accuracy. +* fixed DMA with bad code values: fixes Williams Arcade Classics (corrupted gfx after soft reset). +* fixed horizontal resolution changes during HBLANK: fixes Bugs Bunny in Double Trouble (2nd stage). +* fixed Vertical Counter in interlace mode 1, as observed on real hardware. +* fixed horizontal border width, as observed on real hardware. +* various code improvments & optimizations. + +[Core/CPU] +--------------- +* fixed state of Z80 registers on reset (sound issues with Defender & Defender 2 in Williams Arcade Classics) +* implemented 68k undocumented flags behavior for DIVU/DIVS instructions (Bloodshot / Battle Frenzy) + +[Core/Extra] +--------------- +* improved emulation of copy-protection hardware found in some unlicensed cartridges (Mulan, Pocket Monsters II). +* enabled simultaneous use of multitap & J-CART (Super Skidmarks 6-player mode) +* improved savestate format: added DMA, SVP, cartridge mapping & internal registers state informations +* improved unlicensed ROM mappers emulation +* added Chinese Fighters III mapper support +* added Top Fighter mapper support +* fixed Barver Battle Saga mapper support +* fixed cartridge hardware soft-reset (Game Genie, SVP, ...) +* fixed Game Genie registers byte reads + + +---------------------------------------------------------------------------------------------------------------------------------------------------- +[06/30/10] version 1.4.0 (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +[Core/Sound] + +* completely rewrote sound processing/mixing: sound chips are now clocked with exact output framerate +to ensure 100% smooth video & audio playback, with no lag or skipping, while rendering an accurate number +of samples per frame and keeping PSG & FM chips in sync. +* improved PSG & FM chips synchronization with CPU execution (fixed point precision). +* improved YM2612 core general accuracy (SSG-EG, CSM mode,...) (based upon Nemesis recent tests on real hardware) +* improved YM2612 LFO emulation accuracy: fixes "Spider-Man & Venom : Separation Anxiety" (intro) +* fixed YM2612 bug with Timer B: fixes "Langrisser Hikari II"/"Der Langrisser II" (Sega logo) +* fixed YM2612 context saving/loading. +* fixed YM2612 state on reset. +* removed outdated & less accurate Gens YM2612 core +* added configurable YM2612 DAC resolution emulation. +* added configurable & faster FIR resampler (thanks to Blargg & AamirM), removed libsamplerate support. +* added configurable Low-Pass filtering +* added configurable 3-Band Equalizer (thanks to Neil C). +* added an option to boost SN76489 Noise Channel. +* adjusted SN76489 cut-off frequency. + + +[Core/VDP] + +* added support for CRAM writes during horizontal blanking (Striker, Zero the Kamikaze Squirrel,...) +* added support for 2-Cell vertical scrolling in Interlaced 2 mode +* added support for some undocumented mode register bits +* added proper emulation of HV Counter latch: fixes Sunset Riders intro +* added pixel-accurate emulation of mid-line display on/off (Nigel Mansell World Championship PAL, Ren & Stimpy's Invention PAL,...) +* improved FIFO timings accuracy: fixes Sol Deace intro +* improved sprite masking accuracy (thanks to Nemesis for his test program) +* improved sprites processing accuracy: fixes (un)masked sprites in Mickey Mania (3D level), Sonic 2 (VS mode). +* improved HBLANK flag timing accuracy: fixes Mega Turrican (Sky level) +* improved horizontal blanking & HINT/VINT occurence timing accuracy, as measured on real hardware. +* improved HCounter accuracy in 40-cell mode, as measured on real hardware. +* improved color accuracy in VDP highlight mode to match results observed on real hardware + + +[Core/CPU] + +* updated Z80 core to last version (fixes interrupt Mode 0 timing and some BIT instructions). +* fixed some Z80 instructions timing. +* improved Z80 interrupt accuracy +* improved 68k accuracy (initial Reset timing + auto-vectored interrupts handling). +* improved 68k timing accuracy for DIVU/DVIS (thanks to Jorge Cwik) & MULU/MULS instructions. +* improved Z80 & 68k cpu execution/synchronization accuracy by using Master Clock as common reference (now run exactly 3420 M-Cycles per line). +* modified Z80 & 68k cores to directly use external cycle count instead of intermediate counters. + + +[Core/Extra] + +* added Game Genie hardware emulation (Game Genie ROM is now fully supported). +* added Action Replay hardware emulation (Action replay ROM is now fully supported). +* added S&K "Lock-On" hardware emulation (you can "lock" any games to Sonic & Knuckles). +* added Cartridge "hot swap" feature. +* added missing EEPROM support in some games. +* added accurate TMSS emulation (VDP lock-out) +* fixed Realtec mapper emulation: fixes missing sound in Balloon Boy / Funny World. +* fixed lightgun auto-detection: fixes default cursor position in Lethal Enforcers II. +* lots of code cleanup, bugfixes & optimization. + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [12/14/08] version 1.3.0 (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* YM2612 bugfixes (MAME core): + .fixed EG Decay->Substain transition when SL & DR are minimals: fix tracks #3 and #9 in "Mega Turrican" + .fixed a bug in SSG-EG emulation code: fix Level 1 music in "Alisia Dragoon" + .modified SSG-EG Decay End Level: fix some sound effects (ChainSaw, Zap...) in "Beavis & Butthead" + .improved Detune overflow accuracy: fix very high frequency sounds in many games + .fixed registers 0x20-0x26 Reset state: fix intro music in "B.O.B" + .reverted incorrect fix with KEY ON: fix "Flamethrower" sound effect in "Alien 3" and many others +* adjusted HCounter values: fixes line flickering in "Sonic 3D" bonus stage +* adjusted VINT timing: fixes hang-up in "V.R Troopers" +* improved HBLANK flag accuracy: fixes line flickering in "Gouketsuji Ichizoku" +* fixed broken Z80 access to WRAM: fixes hang-up in "Mamono Hunter Youko" +* modified JCART emulation: fixes corrupted tracks logo in "Micro Machines 2" +* added Blargg's NTSC Filters support (NTSC video artifacts emulation) +* optimized VDP rendering core, rewrote 68k interface (memory handlers, cycle execution, interrupts): greatly improved emulation speed + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [08/26/08] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* YM2612(MAME): fixed LFO phase update for CH3 special mode: fix sound effects in Warlock & Aladdin (thanks to AamirM) +* YM2612(MAME): fixed EG attenuation level on "KEY ON": fix Ecco 2's splash sound +* YM2612(MAME): fixed SSG-EG emulation: fix Bubba'n Stix (Track 5) and many others +* YM2612(MAME): replaced sample interpolation with libsamplerate support, High Quality mode is now more accurate +* implemented cycle-accurate HINT timings: every timing sensitive games/demos are now *finally* working fine +* fixed a bug affecting CRAM/VSRAM DMA timings +* fixed Sprite Attribute Table address mask for VRAM writes +* improved accuracy of 68k access to Z80: fix music in Pacman 2 when entering PAUSE menu +* disabled "Address Error" emulation when UMK3 hack is loaded: fix game crashing after a round ends up +* added support for some more unlicensed games: Pocket Monster, King of Fighter 98, Soul Blade (credits to Haze) +* improved Menacer emulation: fix lightgun support in Body Count & T2: The Arcade Game +* added Konami Justifier emulation: fix lightgun support in Lethal Enforcers 1 & 2 +* added Sega Mouse emulation (Populous 2, Body Count, Shangai 2, Fun'n Games, ...) + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [07/16/08] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* adjusted (again) HINT timings: fix Double Dragon 2 (game freezed), hopefully does not break anything else +* fixed broken EEPROM support for Codemaster games +* modified input update timings: fix Dungeons & Dragons * Warriors of the Eternal Sun (thanks to Notaz) +* added support for "Ultimate Mortal Kombat Trilogy" hack (max. size supported is 10MBytes) +* added (VERY) preliminar support for PICO roms (credits to Notaz for his documentation) +* improved YM2612 emulation (credits to Nemesis for his tests on real hardware): + .implemented phase overflow emulation: improved fix for special music instrument used in Comix Zone, Flashback, Ariel, Shaq Fu... + .improved SSG-EG emulation in MAME core (also based on additional code from Alone Coder) + .improved Timers emulation accuracy + .improved Enveloppe Generator accuracy + .fixed Channel 3 CSM mode emulation + .implemented sample interpolation in MAME core to emulate the chip at original frequency (HQ YM2612 mode, from gens) + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [06/01/08] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* improved HCounter accuracy: fix graphic glitches in "Striker (Europe)" +* improved HINT timing accuracy: fix flickering in "Zero The Kamikaze Squirrel (USA)" +* improved rendering accuracy when backdrop color is modified during HBLANK (Road Rash I/II/III) +* fixed broken Game Genie support + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [04/19/08] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* modified VINT timings a little bit: fix lockup during Desert Strike's intro +* corrected 68k interrupts handling: fix graphic glitches in Darius II/Sagaia + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [04/06/08] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* updated SVP core: fix some perspective issues in Virtua Racing (thanks to Notaz) +* added internal SAT update during VRAM Fill: fix unmasked sprites during Battletech's intro +* fixed m68k core issues with gcc 4.2.3: fix Xperts, Lemmings 2, M1 Abrams Battle Tank +* forced YM2612 Enveloppe update: fix intro music in Batman&Robin (thanks to Aamir) + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [03/01/08] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* added SVP emulation: Virtua Racing is now emulated (big thanks to Notaz and TascoDeluxe) +* fixed VDP registers behaviour when VDP Mode 4 is enabled: fix Bass Masters Classic Pro, Captain Planet & The Planeeters +* corrected a bug in DMA Fill operation: fix James Pond 3, Rockman World/Megaman Willy Wars (corrupted VRAM) +* corrected typo errors in CPU cycle counters update: fix optiom screen music in "College Slam" and probably others games. +* added preliminary support of undocumented YM2612 bug: fixes soundtracks of Shaq Fu, Spiderman, Comix Zone, Ariel and some others +* added support for mappers & copy protection devices used in many unlicensed/pirate cartridges (see cart_hw.c for details) +* rewrote memory handlers for better modularity and some (little) speedup +* reduced Savestate size + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [01/07/08] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* fixed interleaved rom detection: roms with .smd extension should now work fine +* fixed a recently introduced bug in VDP registers writes: fixes bad colors in Toy Story (intro) +* updated list of games using EEPROM: added Sports Talk Baseball (internal memory check fixed) and Brian Lara Cricket +* fixed VINT flag update when VINT is disabled: fixes NCAA College Football +* adjusted DMA timings in H32 mode: fixes flickering in Out of this World, Kawasaki Superbike Challenge & Formula One +* adjusted line rendering and HBLANK timings: fixes flickering in Nigel Mansell's World Championship Racing, Deadly Moves/Power Athlete +* fixed unmapped ROM reads through Z80 Bank: fixes Zombie High (Proto) +* added support for custom ROM/RAM mapping used by Game no Kanzume Otokuyou + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [12/28/07] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* many sourcecode cleanup and optimization +* completely rewrote EEPROM emulation: now support all known EEPROM types (24C01-24C65) and mappers (Sega, Acclaim, EA, Codemasters) +used in a few games (now use internal game database) as external RAM. This should at least fix save support in the following games: + . NBA Jam (alternate Acclaim mapper) + . College Slam, Frank Thomas Big Hurt Baseball (24C65 type) + . NHLPA Hockey 93, Rings of Power (EA mapper) + . Micro Machines serie, Brian Lara Cricket 96/Shane Warne Cricket (Codemasters mapper) +* external RAM is now initialized to 0xFF by default: fix Micromachines 2, Dino Dini Soccer +* fixed SRAM 16-bits memory handlers: fix some Sega Sports and EA Sports games (NFL95, NBA Action 95, NHL97, NHL98,...) +* modified WRITE_xxx & READ_xxx macros for better portability and faster memory access on BIG ENDIAN platform +* completely rewrote BIG ENDIAN support in render.c and vdp.c: rendering should be a little faster +* rewrote ROM bankswitch emulation (Super Street Fighter II): ROM access are faster, using memory pointers instead of reading ROM copy from ARAM +* fixed leftmost Window/PlaneA column render and implemented Window bug (as described by Charles Mc Donald) +* improved "Sprite Limit" and "Sprite Collision" detection accuracy +* modified RGB565 Color Palette to use the full available color range (0-31;0-63) +* implemented "cycle accurate" HV Interrupt timings: fix Sesame's Street Counting Cafe, Legend of Galahad (intro) +* improved VDP access timings accuracy (added FIFO emulation): fix Double Clutch +* improved DMA timings accuracy: fix Winter Olympics (E), Arch Rivals and probably more +* fixed HCounter again: Road Rash serie (I,II,III) don't need timing hacks anymore +* fixed VCounter in Interlaced 2 mode: fix Combat Cars "VS-Mode" +* improved Interlaced 2 mode (double resolution) rendering: Sonic 2, Combat Cars ("VS-Modes") look far better +* added TMSS BIOS support (optional) +* rewrote part of the YM2162 MAME's core: fixed internal FM timers handling, removed non-YM2612 emulation code and unused multiple cpu support +* implemented "cycle accurate" FM timers & sound samples rendering +* improved Z80 Interrupt timing accuracy: fix Sonic 3 music slowdowns +* updated Z80 & 68000 cores to last MAME versions +* improved Soft Reset emulation: X-Men 2 and Eternal Champions (random character selection) now work more like on real hardware. +* added full overscan emulation (vertical & horizontal borders) for "pixel perfect" aspect ratio (tested against a real genesis) + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [07/20/07] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* corrected TeamPlayer support: fix multiplayer in Gauntlet 4 (Sept. version), Pengo and a lot of others +* added J-Cart support: enable multiplayer in Codemasters games (Pete Sampras, Micromachines games, Super Skidmarks) +* added serial EEPROM autodetection: fix games with bad SRAM informations in header (NBA Jam TE) +* added SVP faking: display 2D graphics in Virtua Racing (the game is however still unplayable) +* added support for more internal IO registers: fixe some unlicensed games (Wisdom Tree games...) +* added preliminary support for unmapped protection device: fix some unlicensed games with special built-in hardware (Squirell King, Lion King 2...) +* added "Soft Reset" combo (in game, use L+Z triggers): this should be like pressing the RESET button on a real Genesis and this is required + in some games to enable special features or even complete the game (ex: X-Men). + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [06/21/07] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* added Multitap support (EA 4-Way Play and Sega Teamplayer): allowed up to four players in games supporting those peripherals +* added partial Sega Menacer lightgun support (use Analog Stick): automatically set when detecting the 6-in-1 Menacer game + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [05/18/07] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* you can now switch between FM cores without reseting the game. FM registers value are automatically restored when switching. +* removed the previous VINT timings modification because it brokes some games (Rocket Knight, Thunderforce III,...) +* added automatic Timing configuration (VDP latency, VINT timing & alternate Line Timing) at game loading, based upon specific romname detection. +This means you can still modify some of these options afterwards but they are now automatically set/unset when loading a game which need +special timing fixes. These fixes are also automatically desactivated when the current game doesn't need them. +For information, games that are actually detected and need special timings to run properly are: + .Legend of Galahad & Road Rash series (single line not rendered properly) + .Sesame Street Counting Cafe (don't boot) + .Chaos Engine/Soldiers of Fortune (graphic glitches on scrolling) + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [05/08/07] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* VINT timings are now a little more accurate: fixes Sesame's Street Counting Cafe +* SN76496 MAX_OUTPUT back to normal +* modified FB_WNOISE value in SN76496 core according to John Kortink's last informations +* added support for Maxim's PSG core, same as used in SMSPLUS (it becomes the default PSG core) +* updated FM core to the latest MAME version +* corrected DAC output level (fixes voices and some special FX being too low) +* added support for Gens YM2612 (FM) core (MAME's one still remains default FM core) +* added configurable preamplification for each sound cores (see Emulator Options) +* added some other configurable sound options (boost overall volume, FM improvment for Gens YM2612) + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [04/11/07] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* corrected MAX_OUTPUT value in SN76496 core: fix PSG sound (SFX) volume + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [03/17/07] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + + * added an option to enable alternate line rendering timing (fix single line error in Road Rash series and Legend of Galahad's Intro) + * Color RAM update now always reset color 0 to border color (fix color glitches in Mortal Kombat,...) (thanks to Noop's for the idea) + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [03/09/07] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* modified HV counter tables (fix graphic glitches in Skitchin's sky, Lotus 2 Recs, Panorama Cotton, Dashin Desperados & maybe more) +* completely rewrote DMA timings emulation so that it works for all games (no more cpu freezing) +* added all DMA tranfer rates handling for each three DMA modes and added dma busy flag emulation +* modified interrupts handling on VDP register #0 and #1 writes (fix Lemmings status bar) +* added VDP RAM write latency (fix Chaos Engine/Soldier of Fortune gfx glitches) +* modified FM timers handling a bit (fix Vectorman2 music) +* corrected Sprite Limit rendering (fix Sonic 1 & Micromachines 2 title screens) +* corrected IO Registers writes (fix Decap' Attack controls, no more need for alternate input) +* corrected 6 Buttons Pad emulation (fix 6buttons detection in Mortal Kombat 3, Comix Zone and other 6-buttons compatible games) +* modified sound mixing a bit according to Generator sourcecode (FM and PSG ratios seems more correct) + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [02/07/07] (Eke-Eke) +---------------------------------------------------------------------------------------------------------------------------------------------------- + +* fixed fm timers (fix missing music in Castle of Illusion, Quackshot, Undead Line, Wonderboy in Monster Lair, Cal 50, Turbo Outrun, Thundeforce 4 and maybe more) +* added complete EEPROM emulation (save support now works fine in Wonderboy5, Megaman Willy Wars, NBA Jam...) (credits to Notaz, adapted from Picodrive code) +* added preliminar dma timing emulation (fix bottom screen in Legend of Galahad) (credits to Notaz, adapted from Picodrive code) +* hack: clear Vint pending after Hint (INT level 4) acknowledge (fix Fatal Rewind) +* hack: modify read_bus16 to return a random value (fake fetch) (fix Time Killers) +* modified cpu execution timings, with more correct hblank and interrupts timing (fix ISS Deluxe, Double Dragon 2 and certainly more) (Based on Gens code) +* modified busreq mechanism: better synchro between z80 & 68k (no need to dejitter anymore) (Based on Gens code) +* added sprite collision detection (fix Strider 2) +* modified dma fill operation for big endian platform (fix Contra Hardcorps gfx garbage) + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [05/25/03] (Charles MacDonald) +---------------------------------------------------------------------------------------------------------------------------------------------------- + + * Fixed a typo that made Z80 banked access to the VDP registers always fail. + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [05/17/03] (Charles MacDonald) +---------------------------------------------------------------------------------------------------------------------------------------------------- + + * Modified the rendering code to handle unaligned longword access to memory. + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [04/20/03] (Charles MacDonald) +---------------------------------------------------------------------------------------------------------------------------------------------------- + + * Modified 68000 emulator to prevent 'tas.b $mem' from writing data back + after a read (fixes Gargoyles). + * Fixed bug in 68000 emulator to swap order of words written for address + register indirect pre-decremented writes (fixes Jim Power graphics). + * Added support for 240-line displays (for Super Skidmarks). + * Rewrote part of the interrupt handling (fixes some raster effects). + * Removed sprite collision detection code (never really worked). + * Optimized sprite rendering inner loop. + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [04/13/03] (Charles MacDonald) +---------------------------------------------------------------------------------------------------------------------------------------------------- + * Finished up memory map for VDP DMA V-bus reads. + * Fixed handling of 68000 writes to I/O chip at even addresses. + * Fixed bit 7 handling of control register in I/O chip. + * Finished up Z80 memory map. + * Added code to handle Genesis hardware lock-ups. + * Removed some faulty code from the 68000 memory map handlers. + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + [03/22/03] (Charles MacDonald) +---------------------------------------------------------------------------------------------------------------------------------------------------- + + * Completed implementation of Z80 banked memory handlers. + diff --git a/genplus-gx/sdl/LICENSE.txt b/genplus-gx/sdl/LICENSE.txt new file mode 100644 index 0000000000..a8d781cfd8 --- /dev/null +++ b/genplus-gx/sdl/LICENSE.txt @@ -0,0 +1,585 @@ + +Unless otherwise explicitly stated, all code in Genesis Plus is released +under the following license: + +Copyright Charles MacDonald +Some portions copyright Nicola Salmoria and the MAME team +All rights reserved. + +Copyright (c) 2006-2013 Eke-Eke +All rights reserved. + +Redistribution and use of this code or any derivative works are permitted +provided that the following conditions are met: + +* Redistributions may not be sold, nor may they be used in a commercial +product or activity. + +* Redistributions that are modified from the original source must include the +complete source code, including the source code for all components used by a +binary built from the modified sources. However, as a special exception, the +source code distributed need not include anything that is normally distributed +(in either source or binary form) with the major components (compiler, kernel, +and so on) of the operating system on which the executable runs, unless that +component itself accompanies the executable. + +* Redistributions must reproduce the above copyright notice, this list of +conditions and the following disclaimer in the documentation and/or other +materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------------------------- + +TREMOR library is distributed under the following license: + +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +---------------------------------------------------------------------------------------- + +NTSC Filter and Blip Buffer libraries are distributed under the +terms of the GNU Lesser General Public License + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/genplus-gx/sdl/Makefile.sdl b/genplus-gx/sdl/Makefile.sdl new file mode 100644 index 0000000000..1dd05ce166 --- /dev/null +++ b/genplus-gx/sdl/Makefile.sdl @@ -0,0 +1,173 @@ + +# Makefile for genplus SDL +# +# (c) 1999, 2000, 2001, 2002, 2003 Charles MacDonald +# modified by Eke-Eke +# +# Defines : +# -DLSB_FIRST : for little endian systems. +# -DLOGERROR : enable message logging +# -DLOGVDP : enable VDP debug messages +# -DLOGSOUND : enable AUDIO debug messages +# -DLOG_SCD : enable SCD debug messages +# -DLOG_CDD : enable CDD debug messages +# -DLOG_CDC : enable CDC debug messages +# -DLOG_PCM : enable PCM debug messages +# -DLOGSOUND : enable AUDIO debug messages +# -D8BPP_RENDERING - configure for 8-bit pixels (RGB332) +# -D15BPP_RENDERING - configure for 15-bit pixels (RGB555) +# -D16BPP_RENDERING - configure for 16-bit pixels (RGB565) +# -D32BPP_RENDERING - configure for 32-bit pixels (RGB888) + +NAME = gen_sdl.exe + +CC = gcc +CFLAGS = `sdl-config --cflags` -march=i686 -O6 -fomit-frame-pointer -Wall -Wno-strict-aliasing -ansi -std=c89 -pedantic-errors +#-g -ggdb -pg +#-fomit-frame-pointer +#LDFLAGS = -pg +DEFINES = -DLSB_FIRST -DUSE_16BPP_RENDERING -DUSE_LIBTREMOR + +SRCDIR = ../core +INCLUDES = -I$(SRCDIR) -I$(SRCDIR)/z80 -I$(SRCDIR)/m68k -I$(SRCDIR)/sound -I$(SRCDIR)/input_hw -I$(SRCDIR)/cart_hw -I$(SRCDIR)/cart_hw/svp -I$(SRCDIR)/cd_hw -I$(SRCDIR)/ntsc -I$(SRCDIR)/tremor -I$(SRCDIR)/../sdl +LIBS = `sdl-config --libs` -lz -lm + +OBJDIR = ./build_sdl + +OBJECTS = $(OBJDIR)/z80.o + +OBJECTS += $(OBJDIR)/m68kcpu.o \ + $(OBJDIR)/s68kcpu.o + +OBJECTS += $(OBJDIR)/genesis.o \ + $(OBJDIR)/vdp_ctrl.o \ + $(OBJDIR)/vdp_render.o \ + $(OBJDIR)/system.o \ + $(OBJDIR)/io_ctrl.o \ + $(OBJDIR)/mem68k.o \ + $(OBJDIR)/memz80.o \ + $(OBJDIR)/membnk.o \ + $(OBJDIR)/state.o \ + $(OBJDIR)/loadrom.o + +OBJECTS += $(OBJDIR)/input.o \ + $(OBJDIR)/gamepad.o \ + $(OBJDIR)/lightgun.o \ + $(OBJDIR)/mouse.o \ + $(OBJDIR)/activator.o \ + $(OBJDIR)/xe_a1p.o \ + $(OBJDIR)/teamplayer.o \ + $(OBJDIR)/paddle.o \ + $(OBJDIR)/sportspad.o \ + $(OBJDIR)/terebi_oekaki.o + +OBJECTS += $(OBJDIR)/sound.o \ + $(OBJDIR)/sn76489.o \ + $(OBJDIR)/ym2413.o \ + $(OBJDIR)/ym2612.o + +OBJECTS += $(OBJDIR)/blip_buf.o + +OBJECTS += $(OBJDIR)/eq.o + +OBJECTS += $(OBJDIR)/sram.o \ + $(OBJDIR)/svp.o \ + $(OBJDIR)/ssp16.o \ + $(OBJDIR)/ggenie.o \ + $(OBJDIR)/areplay.o \ + $(OBJDIR)/eeprom_93c.o \ + $(OBJDIR)/eeprom_i2c.o \ + $(OBJDIR)/eeprom_spi.o \ + $(OBJDIR)/md_cart.o \ + $(OBJDIR)/sms_cart.o + +OBJECTS += $(OBJDIR)/scd.o \ + $(OBJDIR)/cdd.o \ + $(OBJDIR)/cdc.o \ + $(OBJDIR)/gfx.o \ + $(OBJDIR)/pcm.o \ + $(OBJDIR)/cd_cart.o + +OBJECTS += $(OBJDIR)/sms_ntsc.o \ + $(OBJDIR)/md_ntsc.o + +OBJECTS += $(OBJDIR)/main.o \ + $(OBJDIR)/config.o \ + $(OBJDIR)/error.o \ + $(OBJDIR)/unzip.o \ + $(OBJDIR)/fileio.o + +OBJECTS += $(OBJDIR)/bitwise.o \ + $(OBJDIR)/block.o \ + $(OBJDIR)/codebook.o \ + $(OBJDIR)/floor0.o \ + $(OBJDIR)/floor1.o \ + $(OBJDIR)/framing.o \ + $(OBJDIR)/info.o \ + $(OBJDIR)/mapping0.o \ + $(OBJDIR)/mdct.o \ + $(OBJDIR)/registry.o \ + $(OBJDIR)/res012.o \ + $(OBJDIR)/sharedbook.o \ + $(OBJDIR)/synthesis.o \ + $(OBJDIR)/vorbisfile.o \ + $(OBJDIR)/window.o + +OBJECTS += $(OBJDIR)/icon.o + +all: $(NAME) + +$(NAME): $(OBJDIR) $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ + +$(OBJDIR) : + @[ -d $@ ] || mkdir -p $@ + +$(OBJDIR)/%.o : $(SRCDIR)/%.c $(SRCDIR)/%.h + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/sound/%.c $(SRCDIR)/sound/%.h + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/input_hw/%.c $(SRCDIR)/input_hw/%.h + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/cart_hw/%.c $(SRCDIR)/cart_hw/%.h + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/cart_hw/svp/%.c + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/cart_hw/svp/%.c $(SRCDIR)/cart_hw/svp/%.h + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/cd_hw/%.c $(SRCDIR)/cd_hw/%.h + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/z80/%.c $(SRCDIR)/z80/%.h + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/m68k/%.c + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/ntsc/%.c $(SRCDIR)/ntsc/%.h + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/tremor/%.c $(SRCDIR)/tremor/%.h + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/tremor/%.c + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/%.o : $(SRCDIR)/../sdl/%.c $(SRCDIR)/../sdl/%.h + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@ + +$(OBJDIR)/icon.o : + windres $(SRCDIR)/../sdl/icon.rc $@ + +pack : + strip $(NAME) + upx -9 $(NAME) + +clean: + rm -f $(OBJECTS) $(NAME) diff --git a/genplus-gx/sdl/README.txt b/genplus-gx/sdl/README.txt new file mode 100644 index 0000000000..500adecab7 --- /dev/null +++ b/genplus-gx/sdl/README.txt @@ -0,0 +1,146 @@ + +DISCLAIMER: + +THIS IS A VERY BASIC & UNSTABLE PORT WHICH ONLY PURPOSE +IS TO SHOW HOW TO USE GENESIS PLUS GX CORE & INTERFACE IT +WITH SDL IN PARTICULAR. BUILDS ARE NOT MEANT TO BE REALLY +USED FOR ANYTHING ELSE BUT EASIER CORE DEBUGGING ON WINDOWS. +PLEASE DO NOT DISTRIBUTE WIN32 BINARIES WITHOUT THIS NOTICE. +END USERS SHOULD PREFERABLY USE LIBRETRO PORT WITH RETROARCH. + +---------------------------------------------------------------------------- + Genesis Plus (Windows Port) +---------------------------------------------------------------------------- + + based on the original version 1.3 + by Charles Mac Donald + WWW: http://cgfm2.emuviews.com + + version 1.7.4 + backported from Genesis Plus GX + by Eke-Eke + WWW: http://code.google.com/p/genplus-gx + E-mail: ekeeke31@gmail.com + + + What's New + ---------- + + see CHANGELOG.txt + + + Features + --------- + + * accurate emulation of SG-1000, Mark-III, Master System (I & II), Game Gear, Genesis / Mega Drive, Sega / Mega CD hardware models (incl. backwards compatibility modes) + * NTSC (60Hz) & PAL (50Hz) video hardware emulation + * accurate CDD, CDC & GFX chip emulation (Sega/Mega CD) + * CD-DA fader emulation (Sega/Mega CD) + * Mode 1 cartridge support (Sega/Mega CD) + * highly accurate 68000 & Z80 CPU emulation + * highly accurate VDP emulation (all rendering modes, mid-line changes, undocumented registers,…) & timings (HBLANK, DMA, FIFO, HV interrupts,…) + * sample-accurate YM2612,YM2413, PSG, & PCM emulation (all sound chips are running at the original frequency) + * cycle-accurate chip synchronization (68000’s/Z80/YM2612/PSG/PCM) + * high-quality audio resampling using Blip Buffer + * basic hardware latency emulation (VDP/68k, Z80/68k) + * full overscan area emulation (horizontal & vertical color borders) + * optional Game Gear extended screen mode + * internal BOOT ROM support (Master System, Genesis / Mega Drive, Sega / Mega CD) + * optional TMSS hardware emulation (Genesis / Mega Drive) + * support for Blargg's software NTSC filters + * preliminary PICO emulation + * support for raw (.bin, .gen, .md, .sms, .gg & .sg) and interleaved (.smd & .mdx) ROM files + * support for CUE+BIN, ISO+OGG & ISO+WAV CD image files + * 2-buttons, 3-buttons & 6-buttons controllers emulation + * Sega Team Player & EA 4-Way Play multitaps emulation + * Sega Mouse emulation + * Sega Paddle Control & Sports Pad analog emulation + * Terebi Oekaki tablet emulation + * Sega Light Phaser, Menacer & Justifiers lightgun emulation + * Sega Activator & XE-1AP analog controller emulation + * SVP DSP (Virtua Racing) emulation + * J-Cart adapter (Micro Machines & Pete Sampras series, Super Skidmarks) emulation + * Backup RAM (max. 64KB), I2C (24Cxx), SPI (95xxx) & MicroWire (93C46) EEPROMs emulation + * Sega/Mega CD RAM cart (max. 512KB) emulation + * “official” ROM bankswitch hardware (Super Street Fighter 2) emulation + * “official” backup RAM bankswitch hardware (Phantasy Star 4, Legend of Thor, Sonic the Hedgehog 3) emulation + * support for all known unlicensed/pirate cartridges bankswitch & copy protection hardware + * emulation of all known Master System & Game Gear cartridge “mappers” (incl. unlicensed Korean ones) + * Game Genie & Action Replay hardware emulation + * Sonic & Knuckles “Lock-On” hardware emulation + * support for ROM image up to 10MB (Ultimate MK3 hack) + + + Usage + ----- + + The Windows version runs windowed in a 16-bit desktop with 48Hz sound using SDL but + without joystick support. + + + Controls + ----- + + Arrow Keys - Directional pad + A/Q,S,D,F - buttons A, B(1), C(2), START + W,X,C,V - buttons X, Y, Z, MODE if 6-buttons controller is enabled + Tab - Hard Reset + Esc - Exit program + + F2 - Toggle Fullscreen/Windowed mode + F4 - Toggle Audio (Turbo mode must be disabled first) + F6 - Toggle Turbo mode (Audio must be disabled first) + F7 - Load Savestate (game.gpz) + F8 - Save Savestate (game.gpz) + F9 - Toggle VDP mode: PAL(50hz)/NTSC(60hz) + F10 - Soft Reset + F11 - Toggle Border emulation + F12 - Toggle Player # (test only) + + + The mouse is used for lightguns, Sega Mouse, PICO & Terebi Oekaki tablet (automatically detected when loading supported game). + + A SRAM file (game.srm) is automatically saved on exit and loaded on startup. + + + Credits + -------- + + Core(s) improvements & additional features by Eke-Eke + + Original code by Charles MacDonald + + Original Z80 core by Juergen Buchmueller + + Original Musashi 68k core by Karl Stenerud + + Original YM2612/YM2413 cores by Jarek Burczynski & Tatsuyuki Satoh + + Original SN76489 core by Maxim + + Original SVP core by Notaz + + Blip Buffer & NTSC Video filter libraries by Shay Green (Blargg) + + 3-Band EQ implementation by Neil C + + TREMOR VORBIS decoding library by Xiph.org + + Zlib by Jean-Loup Gailly & Mark Adler + + + Aknowledgements + ---------------- + + The following emulator authors: Bart Trzynadlowski, Steve Snake, Stef, Notaz, AamirM + + The regular people at spritesmind.net and smspower.org. + + The MAME team for the CPU and sound chip emulators. + + Nemesis for the researches on the YM2612 and VDP. + + Tasco Deluxe for the documentation of Realtec mapper. + + Haze for the reverse-engineering of many unlicensed games protection. + diff --git a/genplus-gx/sdl/config.c b/genplus-gx/sdl/config.c new file mode 100644 index 0000000000..408cac5423 --- /dev/null +++ b/genplus-gx/sdl/config.c @@ -0,0 +1,52 @@ + +#include "osd.h" + +t_config config; + + +void set_config_defaults(void) +{ + int i; + + /* sound options */ + config.psg_preamp = 150; + config.fm_preamp = 100; + config.hq_fm = 1; + config.psgBoostNoise = 1; + config.filter = 1; + config.low_freq = 200; + config.high_freq = 8000; + config.lg = 1.0; + config.mg = 1.0; + config.hg = 1.0; + config.lp_range = 0x9999; /* 0.6 in 16.16 fixed point */ + config.dac_bits = 14; + config.ym2413 = 2; /* = AUTO (0 = always OFF, 1 = always ON) */ + config.mono = 0; + + /* system options */ + config.system = 0; /* = AUTO (or SYSTEM_SG, SYSTEM_MARKIII, SYSTEM_SMS, SYSTEM_SMS2, SYSTEM_GG, SYSTEM_MD) */ + config.region_detect = 0; /* = AUTO (1 = USA, 2 = EUROPE, 3 = JAPAN/NTSC, 4 = JAPAN/PAL) */ + config.vdp_mode = 0; /* = AUTO (1 = NTSC, 2 = PAL) */ + config.master_clock = 0; /* = AUTO (1 = NTSC, 2 = PAL) */ + config.force_dtack = 0; + config.addr_error = 1; + config.bios = 0; + config.lock_on = 0; /* = OFF (can be TYPE_SK, TYPE_GG & TYPE_AR) */ + + /* display options */ + config.overscan = 0; /* 3 = all borders (0 = no borders , 1 = vertical borders only, 2 = horizontal borders only) */ + config.gg_extra = 0; /* 1 = show extended Game Gear screen (256x192) */ + config.render = 0; /* 1 = double resolution output (only when interlaced mode 2 is enabled) */ + + /* controllers options */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MD_GAMEPAD; + config.gun_cursor[0] = 1; + config.gun_cursor[1] = 1; + config.invert_mouse = 0; + for (i=0;i + +static int check_zip(char *filename); + +int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension) +{ + int size = 0; + + if(check_zip(filename)) + { + unz_file_info info; + int ret = 0; + char fname[256]; + + /* Attempt to open the archive */ + unzFile *fd = unzOpen(filename); + if (!fd) return 0; + + /* Go to first file in archive */ + ret = unzGoToFirstFile(fd); + if(ret != UNZ_OK) + { + unzClose(fd); + return 0; + } + + /* Get file informations and update filename */ + ret = unzGetCurrentFileInfo(fd, &info, fname, 256, NULL, 0, NULL, 0); + if(ret != UNZ_OK) + { + unzClose(fd); + return 0; + } + + /* Compressed filename extension */ + if (extension) + { + strncpy(extension, &fname[strlen(fname) - 3], 3); + extension[3] = 0; + } + + /* Open the file for reading */ + ret = unzOpenCurrentFile(fd); + if(ret != UNZ_OK) + { + unzClose(fd); + return 0; + } + + /* Retrieve uncompressed file size */ + size = info.uncompressed_size; + if(size > maxsize) + { + size = maxsize; + } + + /* Read (decompress) the file */ + ret = unzReadCurrentFile(fd, buffer, size); + if(ret != size) + { + unzCloseCurrentFile(fd); + unzClose(fd); + return 0; + } + + /* Close the current file */ + ret = unzCloseCurrentFile(fd); + if(ret != UNZ_OK) + { + unzClose(fd); + return 0; + } + + /* Close the archive */ + ret = unzClose(fd); + if(ret != UNZ_OK) return 0; + } + else + { + /* Open file */ + gzFile *gd = gzopen(filename, "rb"); + if (!gd) return 0; + + /* Read file data */ + size = gzread(gd, buffer, maxsize); + + /* filename extension */ + if (extension) + { + strncpy(extension, &filename[strlen(filename) - 3], 3); + extension[3] = 0; + } + + /* Close file */ + gzclose(gd); + } + + /* Return loaded ROM size */ + return size; +} + +/* + Verifies if a file is a ZIP archive or not. + Returns: 1= ZIP archive, 0= not a ZIP archive +*/ +static int check_zip(char *filename) +{ + uint8 buf[2]; + FILE *fd = fopen(filename, "rb"); + if(!fd) return (0); + fread(buf, 2, 1, fd); + fclose(fd); + if(memcmp(buf, "PK", 2) == 0) return (1); + return (0); +} diff --git a/genplus-gx/sdl/fileio.h b/genplus-gx/sdl/fileio.h new file mode 100644 index 0000000000..30db2e0ec4 --- /dev/null +++ b/genplus-gx/sdl/fileio.h @@ -0,0 +1,48 @@ +/* + * fileio.c + * + * Load a normal file, or ZIP/GZ archive. + * Returns loaded ROM size (zero if an error occured) + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald + * modified by Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _FILEIO_H_ +#define _FILEIO_H_ + +/* Function prototypes */ +extern int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension); + +#endif /* _FILEIO_H_ */ diff --git a/genplus-gx/sdl/icon.rc b/genplus-gx/sdl/icon.rc new file mode 100644 index 0000000000..0b47594d50 --- /dev/null +++ b/genplus-gx/sdl/icon.rc @@ -0,0 +1 @@ +MAINICON ICON "md.ico" diff --git a/genplus-gx/sdl/main.c b/genplus-gx/sdl/main.c new file mode 100644 index 0000000000..1b867e1cab --- /dev/null +++ b/genplus-gx/sdl/main.c @@ -0,0 +1,934 @@ +#ifdef __WIN32__ +#include +#else +#define MessageBox(owner, text, caption, type) printf("%s: %s\n", caption, text) +#endif + +#include "SDL.h" +#include "SDL_thread.h" + +#include "shared.h" +#include "sms_ntsc.h" +#include "md_ntsc.h" + +#define SOUND_FREQUENCY 48000 +#define SOUND_SAMPLES_SIZE 2048 + +#define VIDEO_WIDTH 320 +#define VIDEO_HEIGHT 240 + +int joynum = 0; + +int log_error = 0; +int debug_on = 0; +int turbo_mode = 0; +int use_sound = 1; +int fullscreen = 0; /* SDL_FULLSCREEN */ + +/* sound */ + +struct { + char* current_pos; + char* buffer; + int current_emulated_samples; +} sdl_sound; + + +static uint8 brm_format[0x40] = +{ + 0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x00,0x00,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x53,0x45,0x47,0x41,0x5f,0x43,0x44,0x5f,0x52,0x4f,0x4d,0x00,0x01,0x00,0x00,0x00, + 0x52,0x41,0x4d,0x5f,0x43,0x41,0x52,0x54,0x52,0x49,0x44,0x47,0x45,0x5f,0x5f,0x5f +}; + + +static short soundframe[SOUND_SAMPLES_SIZE]; + +static void sdl_sound_callback(void *userdata, Uint8 *stream, int len) +{ + if(sdl_sound.current_emulated_samples < len) { + memset(stream, 0, len); + } + else { + memcpy(stream, sdl_sound.buffer, len); + /* loop to compensate desync */ + do { + sdl_sound.current_emulated_samples -= len; + } while(sdl_sound.current_emulated_samples > 2 * len); + memcpy(sdl_sound.buffer, + sdl_sound.current_pos - sdl_sound.current_emulated_samples, + sdl_sound.current_emulated_samples); + sdl_sound.current_pos = sdl_sound.buffer + sdl_sound.current_emulated_samples; + } +} + +static int sdl_sound_init() +{ + int n; + SDL_AudioSpec as_desired, as_obtained; + + if(SDL_Init(SDL_INIT_AUDIO) < 0) { + MessageBox(NULL, "SDL Audio initialization failed", "Error", 0); + return 0; + } + + as_desired.freq = SOUND_FREQUENCY; + as_desired.format = AUDIO_S16LSB; + as_desired.channels = 2; + as_desired.samples = SOUND_SAMPLES_SIZE; + as_desired.callback = sdl_sound_callback; + + if(SDL_OpenAudio(&as_desired, &as_obtained) == -1) { + MessageBox(NULL, "SDL Audio open failed", "Error", 0); + return 0; + } + + if(as_desired.samples != as_obtained.samples) { + MessageBox(NULL, "SDL Audio wrong setup", "Error", 0); + return 0; + } + + sdl_sound.current_emulated_samples = 0; + n = SOUND_SAMPLES_SIZE * 2 * sizeof(short) * 20; + sdl_sound.buffer = (char*)malloc(n); + if(!sdl_sound.buffer) { + MessageBox(NULL, "Can't allocate audio buffer", "Error", 0); + return 0; + } + memset(sdl_sound.buffer, 0, n); + sdl_sound.current_pos = sdl_sound.buffer; + return 1; +} + +static void sdl_sound_update(enabled) +{ + int size = audio_update(soundframe) * 2; + + if (enabled) + { + int i; + short *out; + + SDL_LockAudio(); + out = (short*)sdl_sound.current_pos; + for(i = 0; i < size; i++) + { + *out++ = soundframe[i]; + } + sdl_sound.current_pos = (char*)out; + sdl_sound.current_emulated_samples += size * sizeof(short); + SDL_UnlockAudio(); + } +} + +static void sdl_sound_close() +{ + SDL_PauseAudio(1); + SDL_CloseAudio(); + if (sdl_sound.buffer) + free(sdl_sound.buffer); +} + +/* video */ +md_ntsc_t *md_ntsc; +sms_ntsc_t *sms_ntsc; + +struct { + SDL_Surface* surf_screen; + SDL_Surface* surf_bitmap; + SDL_Rect srect; + SDL_Rect drect; + Uint32 frames_rendered; +} sdl_video; + +static int sdl_video_init() +{ + if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { + MessageBox(NULL, "SDL Video initialization failed", "Error", 0); + return 0; + } + sdl_video.surf_screen = SDL_SetVideoMode(VIDEO_WIDTH, VIDEO_HEIGHT, 16, SDL_SWSURFACE | fullscreen); + sdl_video.surf_bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, 720, 576, 16, 0, 0, 0, 0); + sdl_video.frames_rendered = 0; + SDL_ShowCursor(0); + return 1; +} + +static void sdl_video_update() +{ + if (system_hw == SYSTEM_MCD) + { + system_frame_scd(0); + } + else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + { + system_frame_gen(0); + } + else + { + system_frame_sms(0); + } + + /* viewport size changed */ + if(bitmap.viewport.changed & 1) + { + bitmap.viewport.changed &= ~1; + + /* source bitmap */ + sdl_video.srect.w = bitmap.viewport.w+2*bitmap.viewport.x; + sdl_video.srect.h = bitmap.viewport.h+2*bitmap.viewport.y; + sdl_video.srect.x = 0; + sdl_video.srect.y = 0; + if (sdl_video.srect.w > VIDEO_WIDTH) + { + sdl_video.srect.x = (sdl_video.srect.w - VIDEO_WIDTH) / 2; + sdl_video.srect.w = VIDEO_WIDTH; + } + if (sdl_video.srect.h > VIDEO_HEIGHT) + { + sdl_video.srect.y = (sdl_video.srect.h - VIDEO_HEIGHT) / 2; + sdl_video.srect.h = VIDEO_HEIGHT; + } + + /* destination bitmap */ + sdl_video.drect.w = sdl_video.srect.w; + sdl_video.drect.h = sdl_video.srect.h; + sdl_video.drect.x = (VIDEO_WIDTH - sdl_video.drect.w) / 2; + sdl_video.drect.y = (VIDEO_HEIGHT - sdl_video.drect.h) / 2; + + /* clear destination surface */ + SDL_FillRect(sdl_video.surf_screen, 0, 0); + +#if 0 + if (config.render && (interlaced || config.ntsc)) rect.h *= 2; + if (config.ntsc) rect.w = (reg[12]&1) ? MD_NTSC_OUT_WIDTH(rect.w) : SMS_NTSC_OUT_WIDTH(rect.w); + if (config.ntsc) + { + sms_ntsc = (sms_ntsc_t *)malloc(sizeof(sms_ntsc_t)); + md_ntsc = (md_ntsc_t *)malloc(sizeof(md_ntsc_t)); + + switch (config.ntsc) + { + case 1: + sms_ntsc_init(sms_ntsc, &sms_ntsc_composite); + md_ntsc_init(md_ntsc, &md_ntsc_composite); + break; + case 2: + sms_ntsc_init(sms_ntsc, &sms_ntsc_svideo); + md_ntsc_init(md_ntsc, &md_ntsc_svideo); + break; + case 3: + sms_ntsc_init(sms_ntsc, &sms_ntsc_rgb); + md_ntsc_init(md_ntsc, &md_ntsc_rgb); + break; + } + } + else + { + if (sms_ntsc) + { + free(sms_ntsc); + sms_ntsc = NULL; + } + + if (md_ntsc) + { + free(md_ntsc); + md_ntsc = NULL; + } + } +#endif + } + + SDL_BlitSurface(sdl_video.surf_bitmap, &sdl_video.srect, sdl_video.surf_screen, &sdl_video.drect); + SDL_UpdateRect(sdl_video.surf_screen, 0, 0, 0, 0); + + ++sdl_video.frames_rendered; +} + +static void sdl_video_close() +{ + if (sdl_video.surf_bitmap) + SDL_FreeSurface(sdl_video.surf_bitmap); + if (sdl_video.surf_screen) + SDL_FreeSurface(sdl_video.surf_screen); +} + +/* Timer Sync */ + +struct { + SDL_sem* sem_sync; + unsigned ticks; +} sdl_sync; + +static Uint32 sdl_sync_timer_callback(Uint32 interval) +{ + SDL_SemPost(sdl_sync.sem_sync); + sdl_sync.ticks++; + if (sdl_sync.ticks == (vdp_pal ? 50 : 20)) + { + SDL_Event event; + SDL_UserEvent userevent; + + userevent.type = SDL_USEREVENT; + userevent.code = vdp_pal ? (sdl_video.frames_rendered / 3) : sdl_video.frames_rendered; + userevent.data1 = NULL; + userevent.data2 = NULL; + sdl_sync.ticks = sdl_video.frames_rendered = 0; + + event.type = SDL_USEREVENT; + event.user = userevent; + + SDL_PushEvent(&event); + } + return interval; +} + +static int sdl_sync_init() +{ + if(SDL_InitSubSystem(SDL_INIT_TIMER|SDL_INIT_EVENTTHREAD) < 0) + { + MessageBox(NULL, "SDL Timer initialization failed", "Error", 0); + return 0; + } + + sdl_sync.sem_sync = SDL_CreateSemaphore(0); + sdl_sync.ticks = 0; + return 1; +} + +static void sdl_sync_close() +{ + if(sdl_sync.sem_sync) + SDL_DestroySemaphore(sdl_sync.sem_sync); +} + +static const uint16 vc_table[4][2] = +{ + /* NTSC, PAL */ + {0xDA , 0xF2}, /* Mode 4 (192 lines) */ + {0xEA , 0x102}, /* Mode 5 (224 lines) */ + {0xDA , 0xF2}, /* Mode 4 (192 lines) */ + {0x106, 0x10A} /* Mode 5 (240 lines) */ +}; + +static int sdl_control_update(SDLKey keystate) +{ + switch (keystate) + { + case SDLK_TAB: + { + system_reset(); + break; + } + + case SDLK_F1: + { + if (SDL_ShowCursor(-1)) SDL_ShowCursor(0); + else SDL_ShowCursor(1); + break; + } + + case SDLK_F2: + { + if (fullscreen) fullscreen = 0; + else fullscreen = SDL_FULLSCREEN; + sdl_video.surf_screen = SDL_SetVideoMode(VIDEO_WIDTH, VIDEO_HEIGHT, 16, SDL_SWSURFACE | fullscreen); + break; + } + + case SDLK_F3: + { + if (config.bios == 0) config.bios = 3; + else if (config.bios == 3) config.bios = 1; + break; + } + + case SDLK_F4: + { + if (!turbo_mode) use_sound ^= 1; + break; + } + + case SDLK_F5: + { + log_error ^= 1; + break; + } + + case SDLK_F6: + { + if (!use_sound) + { + turbo_mode ^=1; + sdl_sync.ticks = 0; + } + break; + } + + case SDLK_F7: + { + FILE *f = fopen("game.gp0","rb"); + if (f) + { + uint8 buf[STATE_SIZE]; + fread(&buf, STATE_SIZE, 1, f); + state_load(buf); + fclose(f); + } + break; + } + + case SDLK_F8: + { + FILE *f = fopen("game.gp0","wb"); + if (f) + { + uint8 buf[STATE_SIZE]; + int len = state_save(buf); + fwrite(&buf, len, 1, f); + fclose(f); + } + break; + } + + case SDLK_F9: + { + config.region_detect = (config.region_detect + 1) % 5; + get_region(0); + + /* framerate has changed, reinitialize audio timings */ + audio_init(snd.sample_rate, 0); + + /* system with region BIOS should be reinitialized */ + if ((system_hw == SYSTEM_MCD) || ((system_hw & SYSTEM_SMS) && (config.bios & 1))) + { + system_init(); + system_reset(); + } + else + { + /* reinitialize I/O region register */ + if (system_hw == SYSTEM_MD) + { + io_reg[0x00] = 0x20 | region_code | (config.bios & 1); + } + else + { + io_reg[0x00] = 0x80 | (region_code >> 1); + } + + /* reinitialize VDP */ + if (vdp_pal) + { + status |= 1; + lines_per_frame = 313; + } + else + { + status &= ~1; + lines_per_frame = 262; + } + + /* reinitialize VC max value */ + switch (bitmap.viewport.h) + { + case 192: + vc_max = vc_table[0][vdp_pal]; + break; + case 224: + vc_max = vc_table[1][vdp_pal]; + break; + case 240: + vc_max = vc_table[3][vdp_pal]; + break; + } + } + break; + } + + case SDLK_F10: + { + gen_reset(0); + break; + } + + case SDLK_F11: + { + config.overscan = (config.overscan + 1) & 3; + if ((system_hw == SYSTEM_GG) && !config.gg_extra) + { + bitmap.viewport.x = (config.overscan & 2) ? 14 : -48; + } + else + { + bitmap.viewport.x = (config.overscan & 2) * 7; + } + bitmap.viewport.changed = 3; + break; + } + + case SDLK_F12: + { + joynum = (joynum + 1) % MAX_DEVICES; + while (input.dev[joynum] == NO_DEVICE) + { + joynum = (joynum + 1) % MAX_DEVICES; + } + break; + } + + case SDLK_ESCAPE: + { + return 0; + } + + default: + break; + } + + return 1; +} + +int sdl_input_update(void) +{ + uint8 *keystate = SDL_GetKeyState(NULL); + + /* reset input */ + input.pad[joynum] = 0; + + switch (input.dev[joynum]) + { + case DEVICE_LIGHTGUN: + { + /* get mouse coordinates (absolute values) */ + int x,y; + int state = SDL_GetMouseState(&x,&y); + + /* X axis */ + input.analog[joynum][0] = x - (VIDEO_WIDTH-bitmap.viewport.w)/2; + + /* Y axis */ + input.analog[joynum][1] = y - (VIDEO_HEIGHT-bitmap.viewport.h)/2; + + /* TRIGGER, B, C (Menacer only), START (Menacer & Justifier only) */ + if(state & SDL_BUTTON_LMASK) input.pad[joynum] |= INPUT_A; + if(state & SDL_BUTTON_RMASK) input.pad[joynum] |= INPUT_B; + if(state & SDL_BUTTON_MMASK) input.pad[joynum] |= INPUT_C; + if(keystate[SDLK_f]) input.pad[joynum] |= INPUT_START; + break; + } + + case DEVICE_PADDLE: + { + /* get mouse (absolute values) */ + int x; + int state = SDL_GetMouseState(&x, NULL); + + /* Range is [0;256], 128 being middle position */ + input.analog[joynum][0] = x * 256 /VIDEO_WIDTH; + + /* Button I -> 0 0 0 0 0 0 0 I*/ + if(state & SDL_BUTTON_LMASK) input.pad[joynum] |= INPUT_B; + + break; + } + + case DEVICE_SPORTSPAD: + { + /* get mouse (relative values) */ + int x,y; + int state = SDL_GetRelativeMouseState(&x,&y); + + /* Range is [0;256] */ + input.analog[joynum][0] = (unsigned char)(-x & 0xFF); + input.analog[joynum][1] = (unsigned char)(-y & 0xFF); + + /* Buttons I & II -> 0 0 0 0 0 0 II I*/ + if(state & SDL_BUTTON_LMASK) input.pad[joynum] |= INPUT_B; + if(state & SDL_BUTTON_RMASK) input.pad[joynum] |= INPUT_C; + + break; + } + + case DEVICE_MOUSE: + { + /* get mouse (relative values) */ + int x,y; + int state = SDL_GetRelativeMouseState(&x,&y); + + /* Sega Mouse range is [-256;+256] */ + input.analog[joynum][0] = x * 2; + input.analog[joynum][1] = y * 2; + + /* Vertical movement is upsidedown */ + if (!config.invert_mouse) + input.analog[joynum][1] = 0 - input.analog[joynum][1]; + + /* Start,Left,Right,Middle buttons -> 0 0 0 0 START MIDDLE RIGHT LEFT */ + if(state & SDL_BUTTON_LMASK) input.pad[joynum] |= INPUT_B; + if(state & SDL_BUTTON_RMASK) input.pad[joynum] |= INPUT_C; + if(state & SDL_BUTTON_MMASK) input.pad[joynum] |= INPUT_A; + if(keystate[SDLK_f]) input.pad[joynum] |= INPUT_START; + + break; + } + + case DEVICE_XE_A1P: + { + /* A,B,C,D,Select,START,E1,E2 buttons -> E1(?) E2(?) START SELECT(?) A B C D */ + if(keystate[SDLK_a]) input.pad[joynum] |= INPUT_START; + if(keystate[SDLK_s]) input.pad[joynum] |= INPUT_A; + if(keystate[SDLK_d]) input.pad[joynum] |= INPUT_C; + if(keystate[SDLK_f]) input.pad[joynum] |= INPUT_Y; + if(keystate[SDLK_z]) input.pad[joynum] |= INPUT_B; + if(keystate[SDLK_x]) input.pad[joynum] |= INPUT_X; + if(keystate[SDLK_c]) input.pad[joynum] |= INPUT_MODE; + if(keystate[SDLK_v]) input.pad[joynum] |= INPUT_Z; + + /* Left Analog Stick (bidirectional) */ + if(keystate[SDLK_UP]) input.analog[joynum][1]-=2; + else if(keystate[SDLK_DOWN]) input.analog[joynum][1]+=2; + else input.analog[joynum][1] = 128; + if(keystate[SDLK_LEFT]) input.analog[joynum][0]-=2; + else if(keystate[SDLK_RIGHT]) input.analog[joynum][0]+=2; + else input.analog[joynum][0] = 128; + + /* Right Analog Stick (unidirectional) */ + if(keystate[SDLK_KP8]) input.analog[joynum+1][0]-=2; + else if(keystate[SDLK_KP2]) input.analog[joynum+1][0]+=2; + else if(keystate[SDLK_KP4]) input.analog[joynum+1][0]-=2; + else if(keystate[SDLK_KP6]) input.analog[joynum+1][0]+=2; + else input.analog[joynum+1][0] = 128; + + /* Limiters */ + if (input.analog[joynum][0] > 0xFF) input.analog[joynum][0] = 0xFF; + else if (input.analog[joynum][0] < 0) input.analog[joynum][0] = 0; + if (input.analog[joynum][1] > 0xFF) input.analog[joynum][1] = 0xFF; + else if (input.analog[joynum][1] < 0) input.analog[joynum][1] = 0; + if (input.analog[joynum+1][0] > 0xFF) input.analog[joynum+1][0] = 0xFF; + else if (input.analog[joynum+1][0] < 0) input.analog[joynum+1][0] = 0; + if (input.analog[joynum+1][1] > 0xFF) input.analog[joynum+1][1] = 0xFF; + else if (input.analog[joynum+1][1] < 0) input.analog[joynum+1][1] = 0; + + break; + } + + case DEVICE_PICO: + { + /* get mouse (absolute values) */ + int x,y; + int state = SDL_GetMouseState(&x,&y); + + /* Calculate X Y axis values */ + input.analog[0][0] = 0x3c + (x * (0x17c-0x03c+1)) / VIDEO_WIDTH; + input.analog[0][1] = 0x1fc + (y * (0x2f7-0x1fc+1)) / VIDEO_HEIGHT; + + /* Map mouse buttons to player #1 inputs */ + if(state & SDL_BUTTON_MMASK) pico_current = (pico_current + 1) & 7; + if(state & SDL_BUTTON_RMASK) input.pad[0] |= INPUT_PICO_RED; + if(state & SDL_BUTTON_LMASK) input.pad[0] |= INPUT_PICO_PEN; + + break; + } + + case DEVICE_TEREBI: + { + /* get mouse (absolute values) */ + int x,y; + int state = SDL_GetMouseState(&x,&y); + + /* Calculate X Y axis values */ + input.analog[0][0] = (x * 250) / VIDEO_WIDTH; + input.analog[0][1] = (y * 250) / VIDEO_HEIGHT; + + /* Map mouse buttons to player #1 inputs */ + if(state & SDL_BUTTON_RMASK) input.pad[0] |= INPUT_B; + + break; + } + + case DEVICE_ACTIVATOR: + { + if(keystate[SDLK_g]) input.pad[joynum] |= INPUT_ACTIVATOR_7L; + if(keystate[SDLK_h]) input.pad[joynum] |= INPUT_ACTIVATOR_7U; + if(keystate[SDLK_j]) input.pad[joynum] |= INPUT_ACTIVATOR_8L; + if(keystate[SDLK_k]) input.pad[joynum] |= INPUT_ACTIVATOR_8U; + } + + default: + { + if(keystate[SDLK_a]) input.pad[joynum] |= INPUT_A; + if(keystate[SDLK_s]) input.pad[joynum] |= INPUT_B; + if(keystate[SDLK_d]) input.pad[joynum] |= INPUT_C; + if(keystate[SDLK_f]) input.pad[joynum] |= INPUT_START; + if(keystate[SDLK_z]) input.pad[joynum] |= INPUT_X; + if(keystate[SDLK_x]) input.pad[joynum] |= INPUT_Y; + if(keystate[SDLK_c]) input.pad[joynum] |= INPUT_Z; + if(keystate[SDLK_v]) input.pad[joynum] |= INPUT_MODE; + + if(keystate[SDLK_UP]) input.pad[joynum] |= INPUT_UP; + else + if(keystate[SDLK_DOWN]) input.pad[joynum] |= INPUT_DOWN; + if(keystate[SDLK_LEFT]) input.pad[joynum] |= INPUT_LEFT; + else + if(keystate[SDLK_RIGHT]) input.pad[joynum] |= INPUT_RIGHT; + + break; + } + } + return 1; +} + + +int main (int argc, char **argv) +{ + FILE *fp; + int running = 1; + + /* Print help if no game specified */ + if(argc < 2) + { + char caption[256]; + sprintf(caption, "Genesis Plus GX\\SDL\nusage: %s gamename\n", argv[0]); + MessageBox(NULL, caption, "Information", 0); + exit(1); + } + + /* set default config */ + error_init(); + set_config_defaults(); + + /* mark all BIOS as unloaded */ + system_bios = 0; + + /* Genesis BOOT ROM support (2KB max) */ + memset(boot_rom, 0xFF, 0x800); + fp = fopen(MD_BIOS, "rb"); + if (fp != NULL) + { + int i; + + /* read BOOT ROM */ + fread(boot_rom, 1, 0x800, fp); + fclose(fp); + + /* check BOOT ROM */ + if (!memcmp((char *)(boot_rom + 0x120),"GENESIS OS", 10)) + { + /* mark Genesis BIOS as loaded */ + system_bios = SYSTEM_MD; + } + + /* Byteswap ROM */ + for (i=0; i<0x800; i+=2) + { + uint8 temp = boot_rom[i]; + boot_rom[i] = boot_rom[i+1]; + boot_rom[i+1] = temp; + } + } + + /* initialize SDL */ + if(SDL_Init(0) < 0) + { + char caption[256]; + sprintf(caption, "SDL initialization failed"); + MessageBox(NULL, caption, "Error", 0); + exit(1); + } + sdl_video_init(); + if (use_sound) sdl_sound_init(); + sdl_sync_init(); + + /* initialize Genesis virtual system */ + SDL_LockSurface(sdl_video.surf_bitmap); + memset(&bitmap, 0, sizeof(t_bitmap)); + bitmap.width = 720; + bitmap.height = 576; +#if defined(USE_8BPP_RENDERING) + bitmap.pitch = (bitmap.width * 1); +#elif defined(USE_15BPP_RENDERING) + bitmap.pitch = (bitmap.width * 2); +#elif defined(USE_16BPP_RENDERING) + bitmap.pitch = (bitmap.width * 2); +#elif defined(USE_32BPP_RENDERING) + bitmap.pitch = (bitmap.width * 4); +#endif + bitmap.data = sdl_video.surf_bitmap->pixels; + SDL_UnlockSurface(sdl_video.surf_bitmap); + bitmap.viewport.changed = 3; + + /* Load game file */ + if(!load_rom(argv[1])) + { + char caption[256]; + sprintf(caption, "Error loading file `%s'.", argv[1]); + MessageBox(NULL, caption, "Error", 0); + exit(1); + } + + /* initialize system hardware */ + audio_init(SOUND_FREQUENCY, 0); + system_init(); + + /* Mega CD specific */ + if (system_hw == SYSTEM_MCD) + { + /* load internal backup RAM */ + fp = fopen("./scd.brm", "rb"); + if (fp!=NULL) + { + fread(scd.bram, 0x2000, 1, fp); + fclose(fp); + } + + /* check if internal backup RAM is formatted */ + if (memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20)) + { + /* clear internal backup RAM */ + memset(scd.bram, 0x00, 0x200); + + /* Internal Backup RAM size fields */ + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = 0x00; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (sizeof(scd.bram) / 64) - 3; + + /* format internal backup RAM */ + memcpy(scd.bram + 0x2000 - 0x40, brm_format, 0x40); + } + + /* load cartridge backup RAM */ + if (scd.cartridge.id) + { + fp = fopen("./cart.brm", "rb"); + if (fp!=NULL) + { + fread(scd.cartridge.area, scd.cartridge.mask + 1, 1, fp); + fclose(fp); + } + + /* check if cartridge backup RAM is formatted */ + if (memcmp(scd.cartridge.area + scd.cartridge.mask + 1 - 0x20, brm_format + 0x20, 0x20)) + { + /* clear cartridge backup RAM */ + memset(scd.cartridge.area, 0x00, scd.cartridge.mask + 1); + + /* Cartridge Backup RAM size fields */ + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = (((scd.cartridge.mask + 1) / 64) - 3) >> 8; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (((scd.cartridge.mask + 1) / 64) - 3) & 0xff; + + /* format cartridge backup RAM */ + memcpy(scd.cartridge.area + scd.cartridge.mask + 1 - sizeof(brm_format), brm_format, sizeof(brm_format)); + } + } + } + + if (sram.on) + { + /* load SRAM */ + fp = fopen("./game.srm", "rb"); + if (fp!=NULL) + { + fread(sram.sram,0x10000,1, fp); + fclose(fp); + } + } + + /* reset system hardware */ + system_reset(); + + if(use_sound) SDL_PauseAudio(0); + + /* 3 frames = 50 ms (60hz) or 60 ms (50hz) */ + if(sdl_sync.sem_sync) + SDL_SetTimer(vdp_pal ? 60 : 50, sdl_sync_timer_callback); + + /* emulation loop */ + while(running) + { + SDL_Event event; + if (SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_USEREVENT: + { + char caption[100]; + sprintf(caption,"Genesis Plus GX - %d fps - %s)", event.user.code, (rominfo.international[0] != 0x20) ? rominfo.international : rominfo.domestic); + SDL_WM_SetCaption(caption, NULL); + break; + } + + case SDL_QUIT: + { + running = 0; + break; + } + + case SDL_KEYDOWN: + { + running = sdl_control_update(event.key.keysym.sym); + break; + } + } + } + + sdl_video_update(); + sdl_sound_update(use_sound); + + if(!turbo_mode && sdl_sync.sem_sync && sdl_video.frames_rendered % 3 == 0) + { + SDL_SemWait(sdl_sync.sem_sync); + } + } + + if (system_hw == SYSTEM_MCD) + { + /* save internal backup RAM (if formatted) */ + if (!memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20)) + { + fp = fopen("./scd.brm", "wb"); + if (fp!=NULL) + { + fwrite(scd.bram, 0x2000, 1, fp); + fclose(fp); + } + } + + /* save cartridge backup RAM (if formatted) */ + if (scd.cartridge.id) + { + if (!memcmp(scd.cartridge.area + scd.cartridge.mask + 1 - 0x20, brm_format + 0x20, 0x20)) + { + fp = fopen("./cart.brm", "wb"); + if (fp!=NULL) + { + fwrite(scd.cartridge.area, scd.cartridge.mask + 1, 1, fp); + fclose(fp); + } + } + } + } + + if (sram.on) + { + /* save SRAM */ + fp = fopen("./game.srm", "wb"); + if (fp!=NULL) + { + fwrite(sram.sram,0x10000,1, fp); + fclose(fp); + } + } + + audio_shutdown(); + error_shutdown(); + + sdl_video_close(); + sdl_sound_close(); + sdl_sync_close(); + SDL_Quit(); + + return 0; +} diff --git a/genplus-gx/sdl/main.h b/genplus-gx/sdl/main.h new file mode 100644 index 0000000000..dfa5d8d52e --- /dev/null +++ b/genplus-gx/sdl/main.h @@ -0,0 +1,11 @@ + +#ifndef _MAIN_H_ +#define _MAIN_H_ + +#define MAX_INPUTS 8 + +extern int debug_on; +extern int log_error; +extern int sdl_input_update(void); + +#endif /* _MAIN_H_ */ diff --git a/genplus-gx/sdl/md.ico b/genplus-gx/sdl/md.ico new file mode 100644 index 0000000000000000000000000000000000000000..7cf20f88c4ce7d1b870b7e26a1d77f28df994c3c GIT binary patch literal 42126 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 Xs1{Hypjtq+fNBBN0;&amOAGuz*3qa0 literal 0 HcmV?d00001 diff --git a/genplus-gx/sdl/osd.h b/genplus-gx/sdl/osd.h new file mode 100644 index 0000000000..ad95a52b00 --- /dev/null +++ b/genplus-gx/sdl/osd.h @@ -0,0 +1,35 @@ + +#ifndef _OSD_H_ +#define _OSD_H_ + +#include +#include +#include +#include + +#include +#include + +#include "shared.h" +#include "main.h" +#include "config.h" +#include "error.h" +#include "unzip.h" +#include "fileio.h" + +#define osd_input_update sdl_input_update + +#define GG_ROM "./ggenie.bin" +#define AR_ROM "./areplay.bin" +#define SK_ROM "./sk.bin" +#define SK_UPMEM "./sk2chip.bin" +#define CD_BIOS_US "./bios_CD_U.bin" +#define CD_BIOS_EU "./bios_CD_E.bin" +#define CD_BIOS_JP "./bios_CD_J.bin" +#define MD_BIOS "./bios_MD.bin" +#define MS_BIOS_US "./bios_U.sms" +#define MS_BIOS_EU "./bios_E.sms" +#define MS_BIOS_JP "./bios_J.sms" +#define GG_BIOS "./bios.gg" + +#endif /* _OSD_H_ */ diff --git a/genplus-gx/sdl/readme-sdl.txt b/genplus-gx/sdl/readme-sdl.txt new file mode 100644 index 0000000000..3c8eb6485a --- /dev/null +++ b/genplus-gx/sdl/readme-sdl.txt @@ -0,0 +1,5 @@ +Compile with MinGW. +You will also need to install the SDL library (http://www.libsdl.org/). +Zlib is required for zipped rom support. + +Please distribute required dlls with the executable. \ No newline at end of file diff --git a/genplus-gx/sdl/unzip.c b/genplus-gx/sdl/unzip.c new file mode 100644 index 0000000000..ef52bc6269 --- /dev/null +++ b/genplus-gx/sdl/unzip.c @@ -0,0 +1,1294 @@ +/* unzip.c -- IO on .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Read unzip.h for more info +*/ + + +#include +#include +#include +#include +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else + #include +#endif + + +#ifndef local + #define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + + +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ + !defined(CASESENSITIVITYDEFAULT_NO) +#define CASESENSITIVITYDEFAULT_NO +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +const char unz_copyright[] = + " unzip 0.15 Copyright 1998 Gilles Vollant "; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile;/* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + uLong offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read*/ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + FILE* file; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ + FILE* file; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ + uLong num_file; /* number of the current file in the zipfile*/ + uLong pos_in_central_dir; /* pos of the current file in the central dir*/ + uLong current_file_ok; /* flag about the usability of the current file*/ + uLong central_pos; /* position of the beginning of the central dir*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ +} unz_s; + + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unzlocal_getByte(fin,pi) + FILE *fin; + int *pi; +{ + unsigned char c; + int err = fread(&c, 1, 1, fin); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ferror(fin)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unzlocal_getShort (fin,pX) + FILE* fin; + uLong *pX; +{ + uLong x ; + int i = 0; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unzlocal_getLong (fin,pX) + FILE* fin; + uLong *pX; +{ + uLong x ; + int i = 0; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (fileName1,fileName2) + const char* fileName1; + const char* fileName2; +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) + const char* fileName1; + const char* fileName2; + int iCaseSensitivity; +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#define BUFREADCOMMENT (0x400) + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local uLong unzlocal_SearchCentralDir(fin) + FILE *fin; +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (fseek(fin,0,SEEK_END) != 0) + return 0; + + + uSizeFile = ftell( fin ); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (fseek(fin,uReadPos,SEEK_SET)!=0) + break; + + if (fread(buf,(uInt)uReadSize,1,fin)!=1) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer + "zlib/zlib109.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +extern unzFile ZEXPORT unzOpen (path) + const char *path; +{ + unz_s us; + unz_s *s; + uLong central_pos,uL; + FILE * fin ; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + fin=fopen(path,"rb"); + if (fin==NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(fin); + if (central_pos==0) + err=UNZ_ERRNO; + + if (fseek(fin,central_pos,SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(fin,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + fclose(s->file); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) + unzFile file; + unz_global_info *pglobal_info; +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) + uLong ulDosDate; + tm_unz* ptm; +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unzlocal_GetCurrentFileInfoInternal (file, + pfile_info, + pfile_info_internal, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + unz_file_info_internal *pfile_info_internal; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extrafile,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentfile,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo (file, + pfile_info, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (file) + unzFile file; +{ + int err=UNZ_OK; + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (file) + unzFile file; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) + unzFile file; + const char *szFileName; + int iCaseSensitivity; +{ + unz_s* s; + int err; + + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + return err; +} + + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, + poffset_local_extrafield, + psize_local_extrafield) + unz_s* s; + uInt* piSizeVar; + uLong *poffset_local_extrafield; + uInt *psize_local_extrafield; +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (fseek(s->file,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + int Store; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + Store = s->cur_file_info.compression_method==0; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->file=s->file; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if (!Store) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + + s->pfile_in_zip_read = pfile_in_zip_read_info; + return UNZ_OK; +} + + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (file, buf, len) + unzFile file; + voidp buf; + unsigned len; +{ + int err=UNZ_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if (len>pfile_in_zip_read_info->rest_read_uncompressed) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) + return UNZ_ERRNO; + if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1, + pfile_in_zip_read_info->file)!=1) + return UNZ_ERRNO; + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if (pfile_in_zip_read_info->compression_method==0) + { + uInt uDoCopy,i ; + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) + unzFile file; + voidp buf; + unsigned len; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) + return UNZ_ERRNO; + + if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) + unzFile file; + char *szComment; + uLong uSizeBuf; +{ +/* int err=UNZ_OK; */ + unz_s* s; + uLong uReadThis ; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (fread(szComment,(uInt)uReadThis,1,s->file)!=1) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} diff --git a/genplus-gx/sdl/unzip.h b/genplus-gx/sdl/unzip.h new file mode 100644 index 0000000000..a30f79cb44 --- /dev/null +++ b/genplus-gx/sdl/unzip.h @@ -0,0 +1,273 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Copyright (C) 1998 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + Encryption and multi volume ZipFile (span) are not supported. + Old compressions used by old PKZip 1.x are not supported + + THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE + CAN CHANGE IN FUTURE VERSION !! + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* for more info about .ZIP format, see + ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip */ + +#ifndef _unz_H +#define _unz_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer + "zlib/zlib111.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */ diff --git a/output/dll/libgenplusgx.dll b/output/dll/libgenplusgx.dll new file mode 100644 index 0000000000000000000000000000000000000000..118904bc49ae8a08dcdeed1718e1ea9a5a69da89 GIT binary patch literal 2545152 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 z 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

}*LS)T-Wu4YgZxfuou!AKydtnh?;AmrFF zkGo-+J42K}BYXKXSVhIT`?={>c09yT(@~E}MkV@fbY3~7?3BNMzlQQ0@&D?Af1f{m zqa6L=45BAw0nJXY@!;){zy7<@?MvrKYxM&R$c~=W4Gh?+0hE z??wEYp)W6@(X#4G-M#J%_oOd$zJE9A3&Bh>qUeW_zDQ8ZvOIH-hVtz40(}(tzjeXC z(I37s5cVsB=mA+kv(sx-H9)>sEAqWHD)*HiXExpWh;@eTCCvYhXqTp|b9q2=Hk*EL6>t_s%f#2g5`I?ob2o2u$?*s1~1#f_Nyeh&Qrr>S6 z)13tx`bH97Sizg?9q*MI;Hmy+xMw^euXIeO+pIzM`U!dU{=F%$|8s{IdHu{CkXKo_ zC9fyqVfV@F>}v3PgW~U-Zg(#tJHL#9gs1i|W_ickJ|B3C75WBv$EzZ|It6drZJz5p zlJI6Kcym4D33-)AWR?ws2FUymU?^&LFe9!Xa<9qJUc>g|=YuWi_%G2l2P42opo%{pHlX|{? z2_AN{JbCAbS-%H8bHr8&^&cE10H@2B%` zHPYS6zt81HpWFHV{T2Gc-9?`<{T7N}mHGTNHSX2VP2c_p-TEBbgS?rOybJ>YFtt{U z);|kDiW|*NpE3KJsPBu)`kba}uk|$s5?+gfH_JQT_M3sXLBSi~9j}V;)b&!^=6kKL zi2teCGCg5V@dLS| zs2vj!6(z_q|L?2rnwjp*^h~C?{QoBTRM&T^t6sf&_1>%M>h9`xL{F_>dEV38nGbqu z`)uQm9VE&@&M|^?3NK_w>$A1wHlifkV8fw~FYkP>t88W_#V< zu|%(4MQ^1$dM@{`QfLwTq1xY{nck(_Ki@5X%rq|@f81WLyth&I>L_WK`}==3OEO*W z_V-_e(%#sx8+$uA1^TCcp0A5WU2f=A5WQU0`rCnfT=VXRULw&`ujiF}Pw!|B=xtN+ z*VlV`ONgF&y||{>O?$lkd=*zm9uIqDSAMJ>q`u7UWa}a;PWo{$pw~j4wIn`Z0LpEKn_V=HR z(%#sx8+%(d0s5zYKIGJN*LAs}H{Q1SJPkvtcVO*AL+n2NFud?%*1w}M^fB()X=#BBXU!Tbz zi~irQ?*D17t8-&N?TB8zie8@g^mdK`z1CkTpNDVbJ-rg5*GENf``uo*H-_kqQqi03 zH9e*MT!j7h74~xx>XYqfATF~TZ$BNUI@*ti`}^1Bx$a!W%8K;EjeaNIf&Lz>>hE%m zD%{XJIvVtHRrLCLPj3m)D^t;{$#pFPH~g81-U=1HXT7I)b`XYr|N?dj~-d=vmakLi?_xJx0g&Hx|xY3{Rk?8ODRQ)|#qY5|l)@Om6at@9FK#1ii&7dTrd%b9sFw+Y7yma=Gm9PuDA# z4?nWKy@t!$#@k!zL}qX2ZGZnb&})P#IvLH}-k-})ccNeG?s8qPJN+km`&Igy=RLih zX`t8V8>M}=@t$4@(Ho_rw>{hI_QnvsG8Mhq-qSmn3VMrG^tyOYuY%}xKB$!6feBu> zH<9QKR?#c>p5DwHKlzh}LtcXkBmjZ)DY;*Orn z_Y3*@>>uOY`77}=%F@XF{a25ZpF1H2urI_?{BEQ}a^o+K4u?E)Rr2VoQH>jVONd^* zieAlF*KE6?XCiuozg6|W_w>%1KyQVL-VpEUts;7&ir%R)UblBF(HmT?Z0}0%>4g)$ zTot|1-qTw@4D=SO=!JSuFQ4eutLUw}(`)&)BYI_rmGaB;p5D%(ptnLruZ{QgN{F7Q zqPP7HuiG0#^g4g1Z0~IE=^ebCKWTL&-i(f^6}X|delW>P zMK9EQdig}}Jr%umBV7wXo4;JTnpsA#@TZ6`W9bCD#_%oKE9EWO)%&jx)2Ph-`t7Pg zB;W6q@;#O1hJTm(qqX1uUM$_9J&sL$3A249(SG~XaCx^UhyC_rW3P@B-$_&Nw?9f| zP~LC94|3I8rTz8?0AIlU_DcprUV~Ng+Mek~UX_B2{cw5b+VLasX#nA<`+JN= zW$ycXy%GHHSMeXJK~h^^#eAX{@`F-;)@67r53wE58?2(2=QTa9QC{!2UoimutWfcD zAl>WsB@(^;DthJK(>vN9^jiO@lz(6E=`A68D^&DqV1TY1x*Pp45xsg9y=T3rceWqs zbrzNF9pXK`RYWgWMekIq*Xc zB!3k@HN(AbpNZ&+Dtga)Pw(ulPUsDBN6+PaMO=dYWj&qm^8NO|GAZY~pWwGE_t;=f z)s4SwN9`-CRq9usMg?x@?Mwu{{VIBGyr&m~nT+F9eAh5HZP(_n;ae}-`NdV3<~i0s zTwnbn9yd_XJ2zBUd&F=Ry|;AITYpZ;-#DH0@>TSj>7>_AMQ_9H`sBCstg^iYI_Z_D z=(X2LFGfXg*ARW}J$Odh-Z?tyRjBB7(@8H;MeopHeeFGZTG`%(I_WJ@(YsYAJ(G&w zu|fLUd-hLddtcN^Z7=** zgp%Gko%Hfm^qT3U*G@%mLy|uE?fgyI-U6NUN>udP>!cT>qPOcdeeFH?tFpawbkeI( z(d(v@UZRTLpG|>TB=W5Wy< zJ9mq|_J*tIy`_`h`k$5Z8>f?AzKUKmo%GtN=xs>QC%>J?lvXAp4n{IrW(j6yKlie{Q zue55fAJPW~q+Qb@)`k;jsn#gr1>!3NeEFdc$2x!M?WXbkeyhv%t-um& z(~US$de~|egp&uZ-flizX|75_mMCgdd=yc(gwqk9h`e@B>370hL8$sET$XDNZn)uBoy5(Xz5ld68wTw;nZC^9_zX zl#{kRa_L62{Cvm8-b@Po5dg>MJ93s$z8v--#L`)SFW-X$o&@;FQ9aXodLSijezpY7 z24Py!chx-Y^3wj9_ko5h658dR`-j;*;2%g|6#hXQ!`0cJvR-d-N=o&=(g4+Fs zoB0G~_If@+g)gW1MB)wHUl3>Vd}35rH~yk?H}``7%lnJMn{>`6{Bd#TPCeb&gXAy# zT-dgIds<3U2{z+Wm@;_|TpFy{N|y#ue3}wf9rkZp#V-?Fv#o8v&i%=$uJ9+4jX7MO zNC~d|$;T+;nhROEJo6`1k<4859Q27%#^ABQA@+Xa*e^5!uneh1s zOSzzzDBArm9*uV5PdeY|#-Hr(;#p_&{{BnOKdzCys(15`HJv?_kaqt_{>0yFe*!N; zlMi$CgYX(O>wwFUoQZ>B>+mjiyXHu{J- z&t?C!RonoTe{(aRBKEwSPfp4aQ%()Z|eJ54_)Pfl(g+Z@A{Ky+Nr!hf2@rgp0xRK?k}DNQBORZT-r8abhPM9 zcZ|s{PMbeAKcZ=+)A`Xat>KoXJNQm{*n{)#92u+M-F!*uPu$Fx?Ea*&>rZxP!q=Zz z%B7qy<+pI+Pgb;X<4;DlaxZwt{{Kt*lb0p03I(KIYUF&W*OeYhNZUU2u0M%qw<-O} zi&1X)(&k58rJ^@nC%v&Mdgof|<1buA?=7A5)^AnHZ=6ng`6_zNbkb|5qPL-iKKbq3 zqHJ%0PI@IOdhK=6i&4?r^*4R(J@~P*y>oQZt5DJFrjuTxir%5-`r3PRv$DMlb<$g+ zqIauKdL|XUW0CsWdv=quy)Wvdw@O8CxK4UwRrJn9=xcAdir!l~>8;_y$36m?VY2OUWJNYH=XnnRrC&p z>1*%NkCg3QsFU6j6}?+^(le>(9c!wuy=ONl+xwzN^juyqVKPkXs;c`7LqHVw7wBTn zc$%){=(akZY_{J(xE?v=#rNncdIF0cMV43G=w?DdmATr#D1xugZ!p?l};*j{tSw=NWzZqIa&r;@?MZcWo?D0+MVsd_^1EoOz3`gl^d424@E8NIjzO?Zu zV)JR2-{*2J&r_j%Jx{tdOiu`x8Gp`MHo?|9h8nb9)mq2(z@O#kSIpmi$sS>mC}*CI z|0H5f=Fjn;m=ELLG#>cof|s6)k1V3-Sl5R(7TGXJ)vhh;Bp$&ZX!TQuFY&!oVu7k0YEWZ+L3$YzTgYk zBX0Y{iGQhS!urEe&g#Cg%bkR$c&p+Kl=e*SRP`m0_Z499f?0r@>-mH4DaVI7L2h_) zL$5+bubWPKi7I-B0`>8Cbgi@LK3NaLO3cu2p!9}lMn zxRJSY&+9zZEBp7?91p2=j^m-d^?$|j@QmMily<{Da4UZ&<6$0Hau^S}y!m*T;oW%H z0#vzQ=3S;S9*UQ2Je(?Az#ehiA5O-@1J*5;CNW6 z8V~7rFvQ*B1eIH4Q*8MXv(*_l-PX`?dzs>mf0=!n z^%pwi|I_PFdv6Yqwa#3fRP1rj-sP-k<%_4pKQC6#N($k&f1Qly&z@rAhb)Ejb$#0( zRQb5V4NhY`zqr@8G9&XVi#l_A<@U?%b&^J}PN~0Gz3R3vuN|bwlsq3MGGYbkeI((d*_By++O_4xDf|pID0=vS+_MudnSRkjJCW3}^Z-&nLG2 z=0**?oINxw=8b>q0`BPj0~hlNe$B$25Wg7AQLo-#w(HsU-t=ldQRu8^<@vwqAa5*9SZppNcekwH4ZS!Ipd#M(d5e&i>iue1hAm z#(W|HrPZeFyx%Ub`NTaM{Way-MeQ%w^NE;c%JF*FQ8$da8~>Lo>CMqekG|jK_?U1v zo%9k_^bXbOYwyvQl>9B!NpFdY-mN<6nN;+S)#_{S*%y`VeNiX9RVsSJbspxH}(I>y1FDTnvpp#ySie7u2^kP)>c8U7h zd+>Q>d*|q+SD~WUO((rX6}>}0>TB=O=alVTsFU6j6}?+^(le>(9s5CFd(S?rZ10OY z>8(=H8?KYySQWi<-|K5{xQgCeI_a%ntd!q4o%Hfm^qT3U*G@%m!x4S*+xd*Ly#+ey zm8j^o*GVr%MQ_*t^tJck)5`YF(MhjDMX#GqdWkA}hrZL--lL0@?Omvo9(}*dalU)2 zPI@L4y<>;k-f*4t#;WL@tJc@va236`bkbY@q*8w4bkfUL(QBrY zUON@N4d3dM-_9qL?JdwruS7+!y-s>DDtfyP>1*%7$Cd4!qmy2Rie5LJ^b%F{4jt6j z-lLBx+q+OFy(KDox9X&4Qqep1jlTAt{fDx>FY2VXN=0wDPI_Zi^v->)uf5?adT;5Z zw|=2ge&ck~%U98BrjuSf6}=5#>672i3T1l>bkZwP(QB`hUW|&~t^@kodvJlWy>oQZ zt5DJFrjuTxir%69y4s7WnrhkI&HAWm-#M%F?ug?oZ?|=rYEoS zr-+L_KZngY0@*tej!d_A$Fzs^gT8Q1f5R7UgrZGf%m>{DOy_A3)ut!+_MU3K$=a!4 z<)%W>oAI!KeA0Zl3r@;!W2n?r-3_+itbUjG&)EkD@U@3!lhC=#i8S5`Sx!IFEIU&w zqJ+1vjuiLpIcgnshurnJ2_l3bwH{A01Om4NF3O)F*eY}b-0(xUe5C#6i7WbLd;AEp zA_kd6Y#)z^XI4^G6T;q4VxORhG=JyEzCXcIJIf;T_L~xJ`p@C}Aq$9E_Wh92`;N-{ zr)X?W(gT@1=tS-MxqZ@YxASD5L?%W2eUD^6GSSk_bjt~EW6k-@4cFTIq7NndllMBO z-(DYmaVO}qPct|=mF;_7GwqgNo6gy+5Z^lCZ^6;?k9+F5@g8oN@*nzuh4}+BVqW__|sx zUX!E}(rc20m@MTdNlM@h8q)-A`HJB?Y5b&TZ5=zTwd+c>=_$rfqN;equ4*?MKPjER zKBqB$K8f7!TdK{E`h`>3i8^+$3TxAY{jlBq#mrrj{m?H*$sPLC4bvXd|JVinIr`{} zF`vRd)l7HMAjpw*R%?+ww^YB*IEAT(4)rFY}YIIo#fDGj6aw5DJDXW9vC9)LfOKu-lf%r+V!y! zQ`#@x)A5t6;ZlyDRKMzd@isf{}W4q&(pl_ASwW)dl@=`sj<{+hBicrb9J|GWoh3fB5(1=7cto|*W2%)z z)kZTw=2TI?oJM1~ygdc&6r$YL)~g|1t-_kWwdHSXK@ukAaWJb!_?HyV{fqdq8?ClC zL7QKB{y_f4)AH=JwxTj--i|9cnoU(`omG;McU<3Fd9| z1yY+6<10PdeW0!XHhcBMe4rFEYJ|N`@Z4VeY;@C$DtmRQf8x&dG#{W1NF7JH{Z%gM zYs*_K0X;S!uwO}A!k1$68O4S4y`ax$2kw@khq>m(-by>t<}ZhRn^anvkQ?ph5?z}f zR?|sYRo5TSR?^!++fv1!H!v$CS?o@e^I{+K$52FCk)Mv7j)EVL-)9(RK_zw&rZrr_y#O?fZfc-?ND&A&*S(_5n!Fl(ak zZg*TSU-xt0((tPP+=p%?r>#HSf6#b+Ui^oAw@&={eQCTVb#yei;rjT6J`%+gvF8WQ z=^y(*mpsHJpvxD%Y>O1nY7o_yuWUcjM`52ZPI*a=eL4txj4@lKziKTq#tY1ao) ztK6A({-t#Hf#1JVm6RN_oAR`Dsi!=x2k9wKmxg-E(`cuoyz}ugZyoHGHjs1F{0t;I zm9Qjdesm*mQW;L#DK$6ci7S3T$cyrg)-R?X@=Y@@>RZb6Lq~b0A3Dl2{qVlLbNv{y z7WyF*wK`DORd`27f{+_=#%s#-_+M(Y>T5BdIyH~cdF&{3Z0 zhxg^3>qnP&p&v3)n|`!JqSF>OUO&9&SJDp>dc&UbNI#i==qOLD^YwVA($Ln=hFojs zU&{1D2fs`|yf5!uKSKWl{g8>;^y9?8&zpXD&#$B(B(#Q-_FO-7lxO;(qdYa8uQy)| z{bKszJ-^QNqh>YqLndm|k9|mV+M>q$5AXSv^n)6$M?Z9wXZoR|Jkt*yjgT>GykijJoCRg$}|6~qde&vUmtR+O4{;s?vMMfgg=&;UgymB_`i$>@V%druasVC<+g+Ynhs37Fx<|{(Hr*|6 z!2hVRjx+Bmzm2S)9Q38EpOp4e)=x@*DeEVrxs>&j(OruA$JSTX()XXKe$_3phhJs4 zoB|F+toh8HRg`WfeaFM%sVL-ui6{)*8+#>Ja$e=-@_UpDf5Cp>5w>z8c?k#CVXO`D3o@GUkuD zw#$&e;`*v%HrICs_xKmUr_kFxXGF_V$@LZ21?=+Js!KPMjlu_-P`WWbP^Wz}S9rnY z+sOG0&8NCHm`~+h)cMq3PrL3Qv)}^eUoYJMNpPbI6s9$3~)$0Z3RJt~pPdTv) z+kDCog&N~aXx`xMeCoW)%lr9?)6#;gZY$QT9)wSyKTwlU7vg_+Q7FLa`Nl&cWHlI5CbmM&Bd6-XKc>AuzT+!+C<#?Wo zJfQrX!qAr|MZl-L}ucUN1_04)%Ic>T|Hyi&CG1y2P*7Ve;w@eBD7yIp3<%y4&$k+r5-enUtf7Ro?evt9PIO=)aPKI7o|Q2 z`@AUiIoRh#sL!c=hAwcl&!(Q)=RV7Mx6kv|ewXV3@_d)xWubQm)1_n-Merq{R=7ua^@)WZ#z)KV<)x6F=l1 zE+>A-e_THNIQ1_pA7TEb+@#OyY}e?cLC>?%Q(m9cvOgN2FSh)&#&c;$grwr3x%5C3 zdmlALe7cNY&!QVh^j4X<5}$r05MNn*z{!4FWph=Z5<waOrX5HHL!GCl4v=-w^@va}+Nle;LjD7vKwyD?#=?&lP>!e*TU&_#~ zUtB-eNu7?(TR%^;dD42hC;gu-rczz>ZgdWNUr}ljR{{EZD5-#>mZYHJ&=S%LR)PtK ze_pgqr4ta;@dup=>aO`9E7pNIDg*`lF%h4~!b zzOD?|AF<}Y<7! zFso;g-q8QNGS?#+u=-uTKfbgGCLiecGDYHHY(oM?#^8m=gDl|-w&X`ftZkVb5H%NP z%h{1moUnw=7jEkkY2AZYpxc8BCK0Lvj}J8Sj4QjXdn})9@$vf`>AxO>;9UBz#VQ?x zpkq-%LqR7z=#il9O;RB3_KEB7Yh;@~1dk2c|nXaPb2kOH!NPT)H}v=U;{BTo?Y(QQz8X*R5TjZT{s~4F5OF zh5ti(L$iG4evjJB>UZh?L=(&jK2N>@QFS<^X%+cD+qUKwQ$2Q)5nkXMsC1)RjrD93 z8Ld58Wp`-3&m$%sJch^e$`(uSX{7I%3qdyU9em7Pq0%wAa} z&V?UiJB-6vm(!1BeBEanouMCehJLU;X{gK$Iz!7JbcTLNd&*}-w2c(!&Q$FwKL)9M zPx)Nn#_TC?m%h9Csog&owH6;QbnYK#BfX)S&b!AWnY!_hF)%u3{t+U=L#GA^N!mjG zO4P=l5XTAS7M!vt{Jq#CcHH>~yFSAI{k^gN4}x;(|K3ySDEU8B&`_{lJ#2|%FWa%U zycP5D)DM~L`F#8-t@(I=c|N|dNI4&$gWsMmZ80Vpe~q6HN|(acnX>C-kILX`xKWSF z?1haridSOTdw*Iu!=??AKW(kyPkVXFn;U+({st=NgH0sg?x{bmROzbPpOzJREJ|p)__Zjl$S5AYUFkN;k{S zP@Ez0S}{aGPYNrLi;pGm0DC)@cwi59{mT}Ur!~@lCPDBn{pU87PQrgy-|eiUYNvbD zQOp}PJh;&x_58^}e;-0~oy;G{XtSeTpBO&faeQ?Dz>aOn{QCmWq@Z0tH%8lh*k8JVqlt%iOY6!}uf7!3n3HX<}sGy->Eq8k)*oLl!rD)4rF+Y3z--`L! zV_NgGLGt|U*i_~G>=1rC(K;8*Az54gV#!oTf293@lFb*5ZUhtB^>YJv=8yc*TMB>F zS;HS~$@5SyZupV>QS@9?rJQj+C3#2Ause@bthd9@ZhOmgngf|1_P@cyPe3^LDxH8wI(C;c!JNv`>=K98G=y&2r=IUP=*tsm ztjxQkeoWJ5M!P<-U5=xF(SE?n=3h=t_PqVt^>gKS=3ich>=phcR>QyKc*>F+ejNOZ za>mm`@^+kIcmCzLN|)6BWz8hdMW|3BZT|WEhpup(o0@icNBhDI=;!gy{l%9^Z|E<+ zo9IECwCk7rg`eGDYzdl!rf6*VqfJlIo@}uLwWl#pOthb1)4_&MOw_CT82)0zIA?;{ zewPP=QS`F?2Wy|p`J!U}^2)Jmib<6AR5@?_2FYhwsS^16}!h za$Aib(ndd9jjPKxO+)kwJz=`lxVUW7R7BOtDAa~pjMZ3@EjLz|mQ>SvLqvtuUl6t$ z_wm#F*y(+xCHth)U*ojJxUZ|Ry4<+UjMSnw_!&JH`RVgl43y6&UTUw{%HkxPvY0-6 zbP*+%HAilIOA-kYYnnIRZ2^;5Q%6#S#Z+xR9Fb5}(hP|aYeLN1BQ2R9mR*6f3C3!B zs-K*?E#6q&lj^mYw#A$FU0cQKF0z#ll=FSaTJRyrfN8Uc#x{oU)oQ+1%Y3g^^Zg)d z#z~3q)tqm8D)?rpuKAWqgKw5^HRF3VdZ?>$U!$0=AW56I`&%+!VQesYzasPfikj~^ z;2S3;zNG??w>=envsB_6eWVn%R1hq)EUz$@Uy)dDtf=i=FSc{NSmt`Mn(GI^HBL%g zO9jBSJr!KDRHs}^1;I7TvY2tbxF+JP)ml?~#%kS)l|KBDbPKZ<|7}N<#$^=Q#?e&u&Dxj8cfU>c@%y;%wh~#J`ZyV zi!p3@8RGcLoaJK>=UBp7R31Kx{fc5yc@#~dH_VgGH)84gwLS1lo^LFhiz*U~Ara;=SI`$Tf=cjver3@OfONSI*a46j znO|AlQasmO5O|rwpqlGZNM=(p6P@xBpY@Tq2q#N$^5kLpd}60`Jss%-TM>`!4TZa^ zV81(6?C68F&Yg4M-#BD921&|IJ=3EfGkoY32Z9wc;A6QMzbq6r-&bTy$T=L0n-bbwGW zq45s`oyBu$;;V#yBXpWj4WZOWfW9U4457~n#gqa4m(Y`hstENh2U<($UxZc>`kl~n zLPH+~dX~^KLjNH2Bcb_(N-RM46S{T*(BBE=5t>5iTS8+AMOOf&6S|+!5JGzh-A1U@ zLZF_6D*ge~l~DX+KphDkAk>P`h{u7#2`wTNK&Y0`sbHYwCxCt?^a!Ev2^}T$HK8Y; z1lmLB0HLjfrauL=p3u95{zGW!BA}Io4ikEb(4eP*77<9GeD(;Y6#6DG=4Eq zKA~3$O(b-h&}c%b&jO7g^b8>*p|gY%2wnReP#mGrgsvy_4?^t-eN3nYq0@vy3B^4R zWNiZU458l%?Icu7DBuO4!-TpJ`jXIiLOTg9BD9Ine+jK4-;LeCTW zjL_qRLSF=WgwRcdN(fCRG?UQtgz^aOAvB&)@0Wlw3FQ+SN@zKuWI_iB^(GXt6exyJ zPeRucx|>iNLdyt65DH!f6htVI(CHwcnS_2Jw35(|guW$okWkdiK%WsxAhey(-wAz0 z=u1NH5(-}q^ai2+gq9JSP3Rdy{~}aD=zBtDLRY^6G@DQ|q3MMFNoX>mgM{uR)c;kW zR6;8W4I&ir8c-skVnXqRz9!U#Q1U;4IuLq^p_PRGNvOjcKuZWMBJ?Dorf&k36DlS2 zAffA50TmNkLg;Qn@oxcT6WUH_B%$&D0x}W$olt*5meoLg33YrM=q5s65{f32|8JnH z3H^^yb3&v40~Ac?Q$lA0fQ;_|{YK~mLN$cq-Ua%W(3gZhCuCX!^j|{%BUD9b_FAB| zgd*MpT1DtpLdyvytOI(M&>lknAoR%lK=TQ;`vB;ELS{mLCsadd3ZW4n0*xi~E}?Wn zSFZ;eLa3C`ZG>8F0P0Dogiu#P|0C3q(2$RSS`qpep>RS`l|TW6?k98#SK#7dLO&Cl zQU&xqp`C>2`dp0P2(*XLvxK%1vJzTPX!0hY{}B2wp_PQ)66S`fN=2T&-XQbJZtW5wW|K)(~JAXG~zeizVTLMsV%K+#R&tQtg}#nlvb6ubO{=qj<0q88%NT0~*u5sHGuk~;A5^zT+_k&))1 zxTaZWlCEivb;EsY1pk}bMus6=iC{pu0ig%Ntq6k=(h$ZV_a$&AR_#Va0a1CPxL>+RS2CB zx*_yI=!Y;2Aq!yw!c>GJggFRh2u~oqfbbf^YJ~R@HY4mp*pKiXLLI^%2tqIPKSE1{ z_6VI3x+C0zFc2XH;SPjJ2n7iDB0Pk!0O4tbr3kMhyo0a-VH?6;gl`ajKsb)@CqiIv z^glvtgliCPMCgT(gm61T2EsUmT!cb|2M``ccnsk=gjW#WLU<2hBf<`ZFA%B`enL2b za1J2^S7CocXp3+iLM%dWgj*4e2*VK45$-_9M#x2&j&Kh`3Bo)C3&Il!&mt^E_$R_! z2u?3peThB^_#|-IN>TD=mMB_3jad5-{Rjx6m92oPivuF!(tVC5e#pS(Q+MsdrXU~v&lBD*lIIKq=+GdSR!ZcIc?@z(P`8y;4>hO zOJahsNhq2jEsqJpPN68M<|)jdw78jW=Z3Wft7_6a{<4_da6&Ujr{x~jY(ecPEuOwk zvPlTE&DDJr9BFr)TQWncehP_iS<&Z?E|KM#A-FfiZcE~3l`o%jxkQ@9kaA;W z&5ColU0xC?6vcZkE0o2J;mG2hxEF|?ajn!BarB*=c>mK-_u>vyg{giB_}>ylNq*w% zw;i>nh>3}G`?B>W7d)YmTui(V`OTYKN;$33Pc4sYzGFwR-zKQ6xlTw)!yO=tF>tDo zBIYMi&JYOTj!`OCW3eK8Dze5~Ex%e0l$V_8d+VIRwILO+bb`VPk68u=TEhC2KG5b2 zF;pC3$>d&(L zGXIaFj`Q~xwM(~*4VnLSQOl95cUaC@KKbo+OF;R+!1AoH^7!$0jvKo%P@szKe>VOt zzoG>P5>6JSNo^Qf@jNv^;{Sar&^M#anc}9F0cb!~- zKg+3T#QNGGDX};NHEaQ+S(c>0LGW?)z_<6kvN)n|R?Ffm`ewB*4(glLwy1^06gV;~ zRqVj}Crm0lFsyGz>>1m+0LOFp1df>hNAVg-SPfceZ>u)4Mn47(utqOndcgBqqsv(8 zJa(MRjt{Woz3f=Tjx*SC8aw8)<0N*RfFq|Q#R=h+3%f)X`~SA7W?Y}6R^>_jV*NpW ztv+y8C+sw`4Y@5X=XbiROQiXfwJ0Jj1;&_~A`U>`m^Vj`-SmFo_%4xY?_uFwpi{K+ zC*VA3A3NWm24w=Pue2_y8E#Y(XYn6H^(@9n(j(}9Nz3%|`P+W6TFcj0;<$DGW*k8p zcUO8*e+S|@D5Rh>Bhtma%=C~%nJhgYcsZ^)vry|uJX=t678ABF5(TVu&b%(AqGBKN zq)v4>g-LL;iba%MzGw%I^lTNyWfQwZ=K4pXN_t4tvYxm>#mF9QVHqr8>u-U0QqogL ziX|YAX3wvTn12m&cdxAVU+rgJ&$za{ORN@$%>N@|ULa1+Lxt9;x!{tr|B6QCQgX$j z6KAc~v$*fs2!%}jqA)>6*^fc=t5{7wmTe^bq+hH-C89y$5=bd6f zymteqb!V}1O`DHX=!la|w|^2uU+ zWts8Et;QXG&>D*=q};T-BJ;=cOgv$Broyx%b!wB8+_Dz=N!F-)(IvH^^y;&)$ue2o zYCMBs5-)rkf3%p6Pbv>5dZXPtVTV?8ehuF6OIj}Ri!KAd7E@%oX+Pur8;hwW-Y2FO zWbR12kS%a%44~{ELU4P^?jOvFyWuLZ5lBe+{CX%kO)2J8LRNG8;JJy2c~1jcwpIMy z&tiSFdGfry#izRNGFQcvo)SQ2*8LSr&Y)2I_KHcJghwCGfMS+C6;4T%^_XS%qajK2 zwilloS+SlHyKWru=m@_-NU67MtE%z0{QBFgmTl(40q@N~$=_bFYM$^Yp3yDXHSgKgl8@aUEeg6TefO7<>LqL6+YDsF+=T z>6Ui;!9td$I1DZ}q zXTB5fY1uG{$&yG@Ci{LOWA zsgMqNV=hdi8)j==x6sA{R+yFfRAgb$I+&i2aBAjtkG74qWS+rZcB#3qKx%UP%*HbT zbUD5`tgQW@fwkK$CVD`wqUG!@fx*I-z*d5%PD0j)K$Si1lkF*D-Wu?co<;ro81*Yz zk%JB0EZfj5ZbOegKF@3WdCCj>c@r{OM%<=P4ZtuLm?FM^QeiyT#pv!uYxEd4dm6=# z8HzbnYQ?ZlfnB#KZ!Vm?xTux+PbBW?`rw0#pl*W6qec;J>!qjJpE z59XNbA1wNeWj2_P96wNbAfr?3Zy)Fs`R%k$krrUffKIfYcgvxg`Fm%#KhPGFxK5>X zA9HRg?p<3SH18IWt)+RdPGt9iCx5dXKRF3a-i9+RPyP_Fr?6Q9^34h<3{F7ad;EsS z@3m|hcjv}P)m4X$Q2=XnXB#&dZw7P<0Vk17x8WF89E#t8Cl7-_`pLtLs}R)KGJyCC zIe9qXGi};CcFaAMG&5@MDZ|Vr5vz88_R}WI#`wK+4|n)X+!S9Kzn9C@8r_M>#lVgy z;NCcg%wAJ-pFjuZ9*6Ev_0OFPY>nE7Oc*nmKcNp0=8|hpfi79X=~y0~grm9S4AwW; z{G#>-xD|Rz0TbCy7+`YaN<;B(a#uEs&Ry{ceyo*##8;}WF*z^JV%fj-U@Ivd%!za1 zjD`*MnFX@zAS&5TRJ{37NDU@Y2dJi$2WPCj>VAhr_5+=o)8Vv(gjE%z2M zZ;cv-HkBJsm`hFwMeQxd6A8xp;!tFy`BH6ou84W8HEIkp)owE<-iRVXQP|WDVmg|K z8G3F1twEGXxpP~-i+f!m|Hci*C*#_Nj-4_tEyuz#o`_eEYkG=hLXtCsdyzI1YVoYP4%-zRa1%0fs#NfC4toZ6FiZ` zBIYk)!Vpmt9s(fOMZ&1tYCKLUB#b(xFhp~S$b=y#80$zFbW!4582&{O5XL}>y_z1# zC#ePo&`C_NN6aNhgot^#Fv4OysSDVa&g|c6{Dv5?7>|@2F%8_0so(ol(fqv;^Hw6> zYTQldF~_CIV%%>Q1Ivy3ku$+`q_CAGbHDj!p(xxM^$lu5YG1!%|JwaXPRKkm)4w(k zB`hH}M!u2rW$rKcw`P8`j1(9uE%CD3!c^Iod50x)Uqa^YVhpL(3C0~otu3bA<)(c| zEzdk+G48;NHh6^s^VXW%;lZdoj-XxpSvQ186)mU6E~5jp7^%0ZA?A|fLb0;9neo6N zHil{V5NDQgd8RRYowSVh+8ImUN3vhoWpR)=<$CC!F){^{i&Ro#u>*-@bC_1!S$SL^ zC8@7BHXnC=eYDkhgp^4(c}$I#S7St%4V!tADA|(~haoSr3N>_nO#Y*&36B27{mqGW zaEC%s6d4^ZSJE&ag3eH4xshphQA@{DVkWFhK2sc2Lzilb(@#drry+_&GK}Kh%$#Y_ zH%%(JinG;u;_=E$TAM@BK zq8I)Vv;vXEC@g=0#evJ0BCfz&GjG!G`PFBzToxpP8$Y~OwTw#1hy5Ml!lBI~c9YjhsT4iNnaTCQ=rm z_zL72Ddozg8mv(%I18)HK-7pyg|bUDe@XpiYzb8`*A1X6tgX~j!qm1E#t&2Cw-3+C zDZj!R)dLKW>BU!$BR(vqwwBD+7Gq^9*2kjyu#-jqvt(ATGu?q(Q+=-}{=(Almid)) zJ`LDd+9$<`x1~OgSUb2$`pAg2_qMDU5ZtLNmaF5xp1-}Ql_fIa*TPWCxvqaE%s5jR z(%)R!IpIKIO~QeqJNwT~9Q7Ot#(=3j1B1m6V3o`12PPmlZwaFFezif%C?$6iBnp1$ zDm(sGk{=)@kGkVbn9L^MUPQhOee~V&rr$S zip(>pZXQl_W+%=h?24Gzj$m_3zYvMq?~pXEpNU%7RJL1Jg|Qk-VIc^0aF*7+RQ_A! zidbt5N!V13Hwx<#w$2I;z}Q`1h?RCKD^V+6Q}Y^;Gu9I`^vq-;G_XU2c`0B;*vB{u zSaq~U-2(AIN=b+;$7vzrL7d@SphfklnEoq_-=q)&MQL42>Jn}(9E$hg*l3=x?Vc+V zZrM^8l$20a_=jb{mNU2tpDIM7I-%STBB1unkVs%OG=?F_q{w$e1VWYrBLj#LGz7h1 z-AkqYEGbEZL_&QCQD3BV1~MMOU62c737Ted-cHK?tfgZ8U~b}Q((WR>qz6G@1#4M5 z441I8EkSg`Py7QSL$A(XN}|I`HS-*?B)3FbX0r5@P4G5(xtpypW91q)a-+N`&K9%f zu z64q@$T`e`bqT)C$@mngWyzPF(5k^eNy%(fXx6Y?5A)sje%(95`rCIh{zm#dt|GIdE zc|8^ID}KqsvaaweUbIIv*ZUVP9Guhl1tWEFu{p>5q48IsF-6VRje&CHlrLaslFXl2 zyY4ps*(~CrF)+)D!QrK+=;lboBPRT`M70GEmT&`(74uku@<>ZmC;TiQ9B2veOduu1 z5_Ka>3A2R9vJ`p^vzS!j11d64;CARAXoY!mCs;^xTlY4VTb4T)T7t%-?9|W{ zap^Ub6~u=AxA#Gr#Q}}bDy6Z8ktMC3&pdj7_}l>&>5<}oYvaxb4kj_&gYJS zmlEG%A`4WKlFFaUozdX>rq0Fnjq>W1u0*WGf1|4gYgAh-?_dU1QwB|+8X`U;RVdHe z@rE+Evt5E8Vb`Y^=cKFPZz@dRK-fp*%N$zmNfBRVjmORUYK!Rz=-bzTGQR;K_LHu1 zl@|o4nfx;t!36yLTPmcY_;lvH?hoWuN@@`ue}`RfZClv$(c`rjH&s}a^{ zT9UEX&(>0DHJ#Su@xuPv=B0nqEU+jrzOps}(-9;F48Elt1AFF)(wk{A$W9rsAZ4y> zO$%_QGptlom?t|G#1{=580QtLVkR$h9n}vVVfCDm_eP-G0Bif1(W?c`Xt#4Ngc6E5xh)CoF@*z;M9rA$?6@GlP&&8(8~M zqt^C_Rj&V!HPHY4F7zMwKcx#?x}b-mV@7u*MJ$9jfHuI%Tq*B-A}b~K3}G+Bp!Ho% zN6Jm#SfIPC$OEmZ2)d=(jEz%@TiDi|*wwAYxV!c)Ec94XJC%NiTIRCd4>tOhXYR03 z-cg$*XuTYg8vz_(Z%>{7F+gjM zCq@9&;u7ivi5}xP>N*kLe2^fpkB?9dsJ5IjhfF8;ma~gWJ@Z~`^l@+{>m#iL6}OOA zPKvR64Xyl?;XJcD#d4K3x*qA)=rimnu=Vvob_`+1Fm{Y&$Cm8anjPn{{Bzmy0d~BX z9gEnJCTG@Ynz~w}$;(=!$xBFh-Fgp%l$0T;Vg&q5_V-I$W zWk;Hw;qC-GQlD6(si&;bZP~FkJ5opE86g~1j>Y%WCjp-Xd=l_Uz$XEp1bhFtHPbcL_p9Ol+UH`0l+NbB5r{gjOW@2?kpb z{QQu&Ph4z#ykl0ubzacz-dmHd0Q&StbbG`qvJzcC`j$B7!JZd%d-hReM&4j+u(Q0# zs$>Cs>svcmA)1DC!Gp(nd&b78@&*eJ;@?h}=m!TkLEC!9#`jgQD`@5I(Zln+J>xvj z+e;;1*F3~^k9FYT+Es#6eyODyG05A~t`Bp6a-G*S6q)0Cvi{}=XFL#HmbZH!o{hz> z@(zmW*)v|5)g`|vX)$qq``Y;>!mjB;BV!dTxXc@iKQt~bCe~iS6Cv-$50821*#oNP30>B2aY}`N4Fy=S$*>^Aq6bKzXiKo4K>X4lr(2Crthma{=*B9Q zo!h26y2&>(y3CH%c_n^(^nxkbgu(4to!6G({~UOuNm7#3XxfL?F{niWx2pJ?`)ern z_nugZ9 zZ4333HyB8P(|7rbE z{{@z|3UXE6&x7)~a(IEt)4u7vULFtBC{Ow$@z#3=m4EEBhUFRmkvQq(&t85}g1+*b zm*^=!AguI#Do=mB-8`03rDGEz$?>O9Ew?}E^wFWL{Oj~ZFT3p#raynVoU8IyYe1+} z|8|%4(-@-uc2BgF5f8qF@mOHj^stx*IF3-ron7IPM9-oQ!;XTEs5y}t5oCQ|v99@bCtzYd?%m1-A+2OnH@1L4kI zmKTIQr#P(!^5-X1@zUSy^;@modl?K;22aaV?pWc9$XNd?Z0(RJ_>Mja{Iw*2RV}O) zbw`L3(g)I-ZqMF5V(}^1%oJmqAw46_Xv{DS95QHdhB1v_XgjVKNw^nV&?Fq+qbI|o z(O3 zp(6XwL4sd!Wa(T%c)sTpOwNKMI|8RZQ{0`>4an1D^ZVB#y?GMS&AD&1qAPMrpFUU2 z=J>nl%mKh1DgDr~<7SS3ACIjv~B#@#)qaC->a_49C{v8zB-Y&*wwBv;k(W zY3cRsDDSgH-|2)9) zADuov$?=$S@oSEc-CbP8@yN)5nhqV@t2?W`GDg-k3Kq*yPj}!;E$h+&FA=ki64ak3zUA(-3gO8?i10E<9r{{u`Nr1aF4kymqk*VylnQ%Zlz|6?P^y-t12cpy4aYX+efDbJXe-SA~r31_uh zMEb_+YMs}Lbe`dMql!rf7=H2B|2)m{jZY-p$?+#2{rUyRX}#Nh!twU)pU&sFWZn%} z%$MkV5ixHxVba5!Pv7$b$3M60LpsUQS1wxk6~_ggo@~eQzqX!wnd2qz{p827P}lo7 z$Lq>Ze$Vm5&h6qj{$kW|CKIan={ANeo_=D(*XU-c-sji!dzN8HDY5-~_jCN|z=c>b zL>{Ey_T@vYErdVX`1##_@I@U#v#nw0LXJzPojT3&;4`0(;<#zxdvP4^eRSU&9RIh) z&&xR;l>E;RIQ}Z}#1|Z|zANex!UoiPYH(f@#~*z9{b@fTgz-?m=J_8vo?USD!&s?j z={K0Rj^{Z0)hUNLo*!THIL9~6`$^=u+nA0vEWSPlRZ4Vv-_{xaR>Cc2+<`ul@PiBA zoGtiC_?pO|p*;QfPeWF69COcT_;#62*2*xBcJ1YaJ;Y8 zX!N6$r^9z^QT7VfuEj&T9pU(+!Q0U#Qu@LUi`vo{LH+Xi(|xKqex~N5F&r;G_wolE z|7UnM7H_5e%|D%o8!Hn2XXu1CIUafa{8u=Bb$W;QIG$Tzy@liaZh!p9ai`*ik8%84 z`Pf%EK9&5ot?a7u#d~@B{+@5z=o^Y3n#R+EPdwI|yo65^Y2{QBstY;tJ&z!&(oq$HEQ`^z&q zp7uj*HOIw^=b#^@JO_TBmBjJtH5oQJ9~*S0A5Xu!cF@Nh*LAi$$ML2)YhLGg_?y$i zIR5dIG&UcgK7F!j->Z1~&}L7(#qoxg>uv4&VC9Z$c>1;pG4FERYW_=yIL>~1^|u_~ zbLERuIIcRrVFAb66T02Raf{pck(>n>gmCAToA*;X;ZyCZhH;#8q~j5e|9o#}SB^6~ ztRr696$cyAl9cu|G*z-*YWfhg*z5;oSyzu5XVQlx7)+9 zae4`pA(dU#Jn$o)p4Q^!jvP06eEgjpk12V11IJT83(Dd6gI}zNIUbTZsX530t#3Am zSB=6`F^ zGV01!t=kwnUUO}y=4K$qpT0@S{rV3u4jeRiNJ?s2dPZi}$WfywWZyM$ z(&U^exp_1GUO2O;_?}t!&YoNPka^zxhaV{`f9&xmo_uQ2)6Xn^cGp)w`;}ckH08!7 zU825-{p!|d+w6(n*CBAkTOH4}`tHi$Afer-;d}0XH}t9d7(-ao4ZwZHAgt*IC`1|?$`v>?3`Um+p@elS7@ef5YzX1P$fPlb&pnxU; z!2uxwp&;ZJ=pPsm7#J87*d#DGFeES(r2T^Yg93sAgMxyZ1O*3$1cjn9zb5`o0-6Li z32M@$NpO>pCZVX_FW5ggAUH5MD7Z;*aBxU)C>Zh!@ec_I2@DAeX%Z3~5)u*$7X3o~ zLjytsLxVz_ga(I(gocK8i|QD7rhS{Jy4IC#ez-EORZi5gE1O^Sd7E}^=C$~Hi#Au5 zH4AJtAnc>CPh0nI`F7ZQLANydqRE#{wzm1Md1lLIO|A`Y9ojFbV-r)84sDZK+}q^$ z(DdNMh?|4Qht>su*rZL1FZ(PF%m`WKKR)c&>jmMp=6=GMu7Yp^v-uYgp2VzsDALy= zJcm%-6W{5@jQBT*@&H0)gdofd5QI-cP!_YxL$?XSfNVjC$JNF$lOTx5A90Hy)c41A zO+P_6iy6eqs|4YLy9D7Y&~A2}AS?#m&!cgDiEsvwReaG&5SrsE<0Q^?LJ%n(vydVF zg77QCTGTfK@kq>wZVVKJIQ;$*7#%Hqhw>?%1>rv(F?Vl<^rlihtwHAz)bkZ+jYs$y z`MyLwSEHVzICm|=38bGyJ^exZXM_!)dk^9}K)Wqy_r>oTV1M8PC_fctx^=-dW)svM zEC|0N-ikWwQ0K_xEMrc7kpUB2+?)0n2D}Mbz3mScBZW!XMUapnM8|fY)NNMwJ%s7c zph}2Q{T{FSZHQ5ph*nS|ddh?t)$j4D-$YMYLgMTHhvVF`?~|wZ_)SahKNQ_&NX{HEgxwpkrGYVfYQG`F@mM404@&O9E8%oh zF|4b>KSUj12+y53P*)e>=myaYn{;srs%g$3h zwshNgaYfUx@MaPAQRAws+qP@p!9I4}(DlZcZa3LSked^3Nxbzo`#5s@&|#+GBkZHe z9e0iyJ8ryvOqqK3wETkU_L1ej`yVKo^PqivdDOC?V&Ok%l&Sftw(jV$pO63Y>u)E1 z|Knu+sXtGjIeQMv5cGE$@+*ys&prRbk{4fEy6olUue|!&KUb`L{f#$Qz4fovZ~yy0 z@4UO_`yYN3HJc?hPXCeS2!hZrd)lB?E9t{&YYf8)Zo0N8ww3k z;m~Wf>)R zkdb|Nb|Lf6%F-BTnAv1x=M_yiOfNJfPnYqJh;`DrVS^6zalLo;1 z8;sdA8@4~L2jv=`oj;M$&zM{=WpV)}$$ye3N-r*ODm~E0m`n06n3SEz%Q(hyZ2C4} za{dgb%@g7Df~zUq92(zi@JPQQmaN zcJz?@U!``eZdN~&Z`$O7>G!arWCR(Lr%mRaDLr~>oHlu45qcQisNzDpTjARNd$RgX zlM9Lp^X|3PY6sG@#?X%(I15hJp`--k*lnqd8wRHuNXWCY z3za;?vHMc+Kl#~HoVk!V=3oa*o|!kLU~*wY8n|*rMJY39Pl5l+YpDNm%z-s<+crM& zq&{%}>60cKOz_W>3sofI*c5R{0nWe!G!zmhjwqizu_*5zXX*q0PX?Zzn+MCj&X58U z`PoGdgH&7(Qn2KrX~n9FkxGAYJxM`^6y!{wQrK{GBmYn52Ts2iMgbnPi4jK$$MvQT z%DgMjh5mMrCj}jlH?v^!Y-c25Vq&O#!QBPZXF2)}B(lHTh4_Ak+o#W-kuB+VFQJ#> z_fTQz%p*?a^8Fxt*#7is2AV^lCBndI(`U?>Z5U9<8Zu0hZ8prG zmFR)7Dm$MElF^72OzDpGrwM84-Q&CWH>6|4$et!-2pQRTO|y?YSwc$oq)F3kBI+;n z9}vS|{6P&S!8CbFw!t*LcqYp;2)_%mC))Ux+4e>MA4ovfYD4GfNnNNpg9b?!P{2ky zD36q8ym!X*Lh@`le|t8@Xi86q+SyLXzxhdAa|^gcWWyO2xlAcydPn!NxSg!;Be&lZP3M!v~H?>u*eB=SL16VMrf5BExX|h{3~$k2a)@=sy%o zF6_^gJissji+QI0{qZP)GHu8Z11C#_+yzgc-q$FpgjTlBL{YRvw zq#F%GhYTCWnCLfRz-UAN5t+j?r2HA(4GD}=a$5i70Y<~1WRqMI?8P`d8GN#g-QZ*h zj2wXr;xxmsA^pu_VbkzFXT-zLK#qaitM zK-LfgtH(58l#o7%?TV9c<+Q@a zyLy@F$wKkWY~l9g6k%%i48fS0CQL3a6v*TCk^hKi`kSHpn+xWu@c>j5; zf4n@GKd*$lg`T^4Qb*x&H8SJa$)}pXcSdpWrdS-r(|GBmb?~%uDEt|F7G>KI#4S zOaEW*|F-fU?@2x$@R<82wLSCeUtZ4JnAgM0^Llv9{X;|lH)9Sh+g$4MoKMa_=aa|W zU#tDuf)xv%n}I^SeY`x+&tr8t?gyV+^V|xWfa$H@*Z-0Rartw3@|gFJx<6+uko1q| zn9$r7!7aqGFKUb`w`J1o*|Jwb}``z2v*Z;o$CmrDW!^cw|`^JB1 z1mJ#_`}51i|MPzHHul-S&;EV(--mAHu|GbalPlnyME#2c+AW3_(GTG^8z08>vJCS^-6wUli$zYT)lZO9-$EUe1gY3 zKabVr_;V0@kL|5qgYvvy9`ky6?1~PrUvK~EEzkRn$GqQoe4+b~*UMvGFOS{T&*jcz zE_WWglRxiw9`pP>cGv%$PagC9Jm&hw^~V1EO!YBZLf6}WddqXU^O(1T$L{3M%kh|( zPKJyE7woGl|L`XW8QB(cGrKr9FKW99=j{g`<=(U-+Aoof6vxW zyp=yM$79}aJa*TAyc~~tIUc(!&-wjPWlMblIai9P9`Tz5A{m18V-p1GTC@AGnc`%iCqE_WVt zIr7+@{CPPZ^Kv}C(B*kOJm&q*V_*MEGYBpp-XHw=LEdjX=J|Nc^Q-0Q^Z(NGf836} zjrH2E-txTPdCdEr$G-lTMsoEy&gXyL_B$`9xBv8(=l#xO-tRp2^}nzGNe6uXU-AIz z>pyPC-p1U1d3kPkJa%n=QVG4~`TG~VetzA;W3}Jo>#6+xA9Z=oH;>)%&+ENZF<)Qd z^>coCtk!!jmpRYPS#TFGzE@jAmWL@{(tpf9yims^=o$b z&b_<&9iK06c3xL^y;ra5byZjI*2mWa4?Xbzf9pm4c=MadP(AGZv!#}=x1ZT(vZ?*e zzRgvt{pTXU+RxhEWK;WFoLYJ7FD9GjUsi6pq}pHY?_ zRF9_d-|R7Ic38j0{Qdub15Q1ESe~+S_H(^Hhx(W2@NcQ*=gzWx|KHU5zxmsw)o-Ex zUu=21j>(0_pN;n>E#B&RUqrahxHqi z*6&TK|Ic|Kl>b8g?z+aGm0xQ9v-8+>O^!CI0!>GzpZFjSKRNLL`Hb0E2G(U{09MyI=yGOO%&2IC< zs7mw0sLD}oce8s`+uiK0`@#0Hn6&kf`hE`k{XI)9Z`ZN<*nSa{^?ehzFVw&Pa?LA% zR`ma+)yJg0-)Pq{d+`4ILH_+O)7$fZv(sd#9=3mV=;HXn%9&hfd9%-C)Be}`_04XR zW?#sDJI>By$C)&L)$LLHo5zNw`N^c(e=dUR{;>G5I5RJrzf7wC^ZnoEHc2}ZZ`ZNwTfaA{{;&S;W5Dju?7m3%f7WA$rS(UX z8vix^dk@$+YvZ})KZ_HKB0J8c9k20!E)&@}r1{^WNBTdSY4Kyy;>KiC{Md0OE$^Fb z%Kui*q{XSp(0T0l2V1?ZU9FtSaQV3&v()ldZ~HrKmfuV^&Ht^uNvp5PCjVLem)igB zJXQ~rYX7;GsJDZSALb{u|C}c*ZcWzxX8pqM|IB|Tt>2mqok#tDZvE8yt@{652C%p> z8IB)~|H}XC?td10|6t>m#($0fJ_anmnbiH?+#P`RFY}A?|6KmD@x!F$E0az4Ps;yu z9wcB!!|7M4zJRlFq1M+}8AP>j`@_;-b56A=ZfIJ`%Y`Gp- zuIE3tKgp!6x0qz>SN;z;SUHpSyxC-E9p}hXj?DZYU9uLnTzQ~H^qbk$?Y!n^n-}T*pAGZ-AI!fd)&3S~bJF6?{9^rKOL_m_+TEntY0~Vi zk7MfpbN3GxEjE6czf9KsX5*vn|Fm)@ZQL_y?PAxlc(n1)^fs@zb~72Ohqa%TH)-We zHkG$}TY0n3WYhYul{aa2o3!(W?6>2ryd7uK{8hKd`tMT9+jZ>v<}Z_Ke?I>+znQf5 zFsb&R^MJ*f#k2aqe*edY`2Anjzf9UVX)-j9S^ltoYvpa+H>vS|E(2J8HoqwUTjUH& z8~06GT!qFzJI>Bx$C14=k6gx8Fj4wsFg(wY$l1`_GkFF1ziz3$?d?yxDEi>^3R;=R8m!M{NDo z+F`k5y*(HDv$eZPYj=}sf3?5&fZ~771Gdhm{y#TjEZ4Ya*Inp%S3lmyy~Rqa$8yQK zJq!JLv36Uz<+9tZyHI=U$D19Cl~#}Cl689)`txG#wsOm5w_SIk_STO#I~FUg9?K=` z_AK=0#oBG!*|oD* z&MyA+*S%WnDuPcrs6Y?&!CG)7xEjnt4JyzBeXtf>39bgSvrx}MJqz_L)U!~}LOl!h zEYz@U7Pig8x>?va3kzpq~Rh^>y;>Y`}Jt#-oy{eQb$```Z1 z4*$3RR>S|zl?eZTxU_!S)I3nkPB=zytCfzCMb0tWTR9gZ-5R=W!lc_emt2q2+Riyf ze0}Hoz-)-uto!W0tG0I(D;JWT9h_riJHkJNe1&t2&KS;5$j4EhkgbIOCI)P-+3yyJCiBVj)w+J4+Iy3hyNVceBF5>||3?BitPs6U~- z5^X*)+~$M!r#p{3M*C3{j?qVXMsBTRZG`o_CC@q5M`BYN+c>jJBL_mk^B`|pbPjZv&z zNM`SceT4Q0U>_m2;s|chy;Fe}a_@$^4^Zj**tA zKOs9C{$qR$dP4i-@GqhD35@TxHV@e{ir=%`?{zfy`}+ct`@Jrd`~COI|0MVO`vT>E z<^PSG|BIPP$7mW8J8LE#WhdwZR69?)?hV33yI}ITD<|G<(lJ`QPr6n-d2Rly+Y|4B z@`U>F^`G6Is2?HT3+E@KH=1;e&W+(eLU9wcAECVIq$~Fh+h6VjJ)v%I{pVs|T%SRzt^$3zt;ul{(fCx z6PW*}dt-h^Xc`aO`(XaX*cbW$`OUC)aPu(Lewe%8g44St=Cg!;3-jMw4bORpY`Qgc zjE42%?rl&%LT`VZpAa8_^$SA#cJLn|JrM0j$Zn7M^BuzWXLp32FyyOwe39M>*C%9m z#`y`=U9kQ@h!Tv?g!pdoA0fFr{CAJA{Z005>3ZdV<$vY>(arw_o`*4-#=rR1SmPsf zpbHV*2G2GKJ?Pr|b1LW=t=qyr;0_pfIjGyyo<)8j)Q_+K+(%hP6`_6s%B@hRtqI$} z_H8-w_27R(AG&h8_3bu0`gk_Ru;W6q{o+7Nqv&Csn7kWlHgBV*A zw!hp1{vm|yw(r|}qJ0SQUTB{H?nbB=e{sgl#C{eaYsQ!)m z6S`~RKgNHcCzMyfzl6?z(YLQ$XMfO+dDb>Y;aKH=<$vY>(arz;=Ocd;n#REL1sHz` z?H3~d1nA@Y&WpmdUW~E7f$Sxi-x1tPQ9lr}qkSssM+lX(@7>EVzamu7F|wDV{)G4y z$j^i>bd3Bo-2c2XY=6(|7!7%`d=>ml$X*Tm2(1q4N9aSxC|`r?6SCLh{I4VSH`r(G zyroLzf8~GW|Iy9=Tk5zbyZC#X@{j!EV?g;|`Cs{ebn}0;58eSIH06nG-<6IL-)yA| z(S?EunoN+Whvg5u|s(FGINFaQhc`LV3b`HV=MR9E9?O&b?t@ zfc#+eo%@7I?~9ndA1As0O2=qD0R8WQu=_#qLmU1CgY_>T4Brq2kDc#x`6!ep6pw~~ z0(6c*>^vq+mZHrb%V{48{}7U+5PwI*2akgf9uFTJGi-k!KQrdDdGNdHSd5>9{5aSb zAbA4nb9|Tzy8MZp$W&?MmoE*Et#IcqWc}7On>d?I@m&_#_M-JKyK@Ifze!doHdUpu+dr zDPiL0p}q~|Iog)cdOqw0ofn|}Ux-)-gLbgo?{$O6&i9$+ey4nS%aCIU6?Ey#QHNK+PLP~7JfxCWs4KcD;iwE;Hw_qwL}e^dY7()G&!%Kz*hpeg<}|Hr)p z@_Y#8fA~i0|MNZr(E2~}^D?jhH;r#wx?cHT`Cs{8^Z(EufTr<}J^S~%Q118N>-m59 z*}vZxp!vV%|4sdGse0vq<$vXW<$vY>`S$@fjjwF)pVx)<{`v1U|JVG#DZVzgUin}7 zU-@78U-@78f4=tsn(`0Z`|ow3z5o9EO=16klYLvdUin}7f0Xlo7w-cyn)-inXWTmw z(z{^)ZGiZ$h&@7)pzPf^@!hfim(YW*xChR0PaJnIT+g%B0Egf+WANB{K9>){`+tP& zP`u+1p!HDXTtfLUlzlj-br{|;A@rdu563wkf#V*D>w!W0*}H#UH+bxPpEdu-bDYii z{lEFzbd|#??(@lLC5Gq&uHyC;TRq08GYy(?VI86Qxi()+|6MF=z`XM6GLNK34buM9{fgV z{TBWu^r2&vzr*zj+3#_ELhBE>KA{g?`A3}NPdM(+s0$eE-{oJRXZ#g<#^0bP6n{tl zC3OCQ@sp5Wh&5zFb`fkNq!*+A^s&}_3GBZV_W=JKw%=WbK0!$Sg|dX~a$KL#`8Vt% zlxyKXLia!DyM+D~Xj6i_5_Vq&A6$)k&Y~_+E&jKfa3vw%dIEo=BTRc6^gn{z7X6RV zg^tm=9>xbkdplg8;I5DJgU;%OPhwW#%-|JZJ_d1sQy^iI6uVcC2>saphI+pvrPWfN?U-@78U-@78f4=IS`7a-pg_X&F;_j?A`@s$7Jf6f1c zYXEHS?{#eM?{#eM?{#eM?{#eM?{#eM?{%90YyPkKzvlm;`Tt-p9L3Md|H}Vb|Hpku z=otW8`}aDs_V0CU?ceLz+P~MawSTW;YyV!S^?$AZYyCgG{y&O2f6!*-f8~GWf93zs z9su_2-|N`3f3IWD{=JSp`}aEb?BDCyvwyGC^M5`6XV3o!bKxj{R{mH1SN>Q2SN_Kw zah`pEZ111fvAus@$M*ht9ozfob!_jS*Rj2SUZ?$keE;7l=KMjMmH(ChmH(ChmH(Ch z=X(!;?fv&Uw)fxb*xrAyV|)L-j_v*TI=1)U>zele59Y#A{H*-1{IC44{IC44{IC2! z{BGMG_eNd7U|hG}fc;T~ z=#6MULKiwl=S_G9OlZFu@k4NLLHiQA&@novc6S7aEeuUO% zP%lCsI!5_fT%VAA4(I6Vpe|n=w!ify=n3x2@DHI69iyypT|)L1)QQmgD(Xk* zL&qq;hVy?N=Qsz)f$|%}_GjOOp3piMWeI)g7{#{`|Ah8=h)+WFZH&K!5;{hDKHBd) z==UJI0P+9bVf$I`_d1sQy^iI6uVcC2>saphI+pvrj^%!@Q~p=}SN=zzSN>Q2SN>lw z|96oO8J#ZfPYLbsAqNto?;{5iO6VBr50C>1?uW>MgbKRsN67m>hMge)iSqy8{FlxB zy^hWOy^hWOy^hWOz0Q%jzt?3AbT$9i{9p6`;2MDD|CqmO{vVwG59WeV{H*!E*8jEs zk9+vgGXS>s?{#GD-|N`gzt^#~f3IU}|6a$|{=H7?|7atv|7-m}u>L=aIe*Y*<$vXW z<$vY>;2r?>?BDCivwyE+&;GrRJ^S}M_Uzy5*t37H)BIoafA;);Fc*&EXXSt8f8~GW zf8~FyrOdMrknR2RI=1)E>)75uuVZ`vypHYt^E$To&+D}R4?ZCK|3)$A58AB!ul%q4 zul%q4ulzsXdjM?jzt^$7|6a%T{(BwU`|ovZ@4wfvz5iaeJosJbqi7#OQR4c9{@HlPg3$Un;*-$+1pGtDK8e45`Khq|?pE+WVbIq3K1a94 z-v?#f26{qkf7nMzZ;QVl$~XXe#_iyr1H<;uXOq4gojlM#VB9g9VxfKDIN~czeEV_7 z=tIw_?lA5cojZ;@MtY}l*Shn#i|#V+x}do0_|We^X|k_LUv7^z20~N$CcWDM_oajm zbPTs6)>uFnv{tMi*I6>|7)|wy?grly3g|-QcSqaYBTRJ9aaT5w-fP@3+(9@82-%U` zd)zTXA6%c{?mO-n74(ekekgzcu>A#e46`#N;|HLB6DsH!od=@- z64D2ueF?4&`v?_u=^V=s92I#&Bx)+D(z683La>`RNe4=!~Bg9zjDGcl2=VQM*3>hkI{ji@fytkUK_T*^*Yp_&}4rfWht+Ro)Etg{vovA zg!(hy3_as5@bBqi`#bw#{esYFKg#wA$t`ewLI*lV4|+!HmS{gh4qX?-EvyrP3N+ay z{g#*KLv5=3zqGbybAPW3`Te?n&*uJK$L9WC*EIjHK8-Pf&{WU#Gsr)L)@Lz3h4>uq zJw8wP0>-KasxPAcgyKu6-p{rNX>eM0+Ov z<3FMQG~|~6oo68TKQm1EER0#t;grwC_)BO#4`W^)9`n*iPC7=D{oS3MV>Fd-(kDAR z$0(s^#5Zs*2R)G75OS;Gcuym|BTc9uU;o)9Xg@;z`1;TNyC6OY?ru0ggsoS#rZ$4D}iCsfcek|(1)q4K(? zgza~ansf}aGbBrtXXKBbbU}{5z2{>H>7;8tmg9~@{Rw^O%A>;ehwRe#OUnzJi~p4W zm)6dkd;Z^C;#BoqTAXey|0NH^{F2bRAJ%UOP4!A1g!41n&=cB+K>uKHfAD|}KMyV* zhV>;v>mjh8&}4t-;dnm4I1GBm;aH!01Z+PP&j}v7;q7m#zx11CzqNKz{$E=ADE}|b ze-?+!C9|U^-BO6h@H^TAbnw1K>man`eEYs5dJ_Pk}i z@(ucA8`PUnLdS@=#qZDsT@b^U3%$OM-?DwC{J*sJ-Q4qkde1S(XzKs%dyP3pdJxVZ zpt$##D-RCSzt5P9?#FTWAH(}?Vd4jjx%h!&!ErBs5cCAs#<>YObd1g+V~){#FzQB# z4@Lb5$wS8+BYoJI%N`!KKR*ohCuE1CJfR02BYGs-kI;S;;)hT?ddxApM~pc}l)`_H z4cnhS9`{Ow{#)>l5}`s_M(Y^oLiC_Zj|~$YhrJsOL{D&zkwf1Hp?+N4deSjM; zZE&ASDE7zs1N3e?iFeP#v<}3xo7;2RcbIgH^p1GGa;Na~kMz#a6WVvd`3V(tjP6}0 z9V5Qmq+_IaNBs!-JurtL6!*mQpL>PvuMR@}3FW;}o)905`V*4-p#2D)`yze_z5Ai= z1or?u{~{z0g#R8Cwm&@{{g2Q(ecUlBlx4J@i2fg-hwsx9!bB%Jmo?Cbo{>EXecuz9 zXRzGwb)jt|DUiqKret%!Ua=+KH z-0yYD|2+RkPsaT-A$=QuhXA4H`xc?|e5}s~$X|fI`NA;qi?Fx6f&9goBM_38pne|Z z|9O4D=KfyC=KfyC=KfyC=Kfx%{J*^O{|bGd(Rn+5#|R;RDf%D5o$6eO9(4K3!Xz(8 zzil9Y1{Yn;cy*Wxx^{=tgPxJS2J;UP>i?SmV}7Xh|KKwK zw)XFJZ0+Cc*xJ9>v9*7%V{89j$JYM6u4(;0J_&u7(0wOu~S? z`Y?Uy@;7kY8*zU@D4>hq6z>1Z|H}WPy#C)s-)Hm-JpUtf(6<=zo6-LQ^zeQ5mN2c; zF*j+T{Z`x`5PHz1ZwvQ-<$vY>QGWiPKNb0v;LaF#jGpgXgzW9;-vN?$pe&(yC+-aj zP7iuU{w~Zf&ItE^<$vY>QO^IZr{Vb;<4ipNBjo5?40k5(&jWPvefsV&@q4g#&_MED zj1Pn^bnW+r`@izP^8YC3{~r22qy29DZ4*KleT$L4AN@N(>jNlD=zI`k(}y@+=o#6E zvHk!;>wn7s%KxLB|2t2|{GE`!2YWsM{Af1@w&Mix{6k=>A{% zU-^HO^M8fD&*;A&&;JO?myn+cedt2;zKp(Gg~`8ybAOc+eGTISp@J^^dbs~9|11BG za{kYsiS>Iz{6YK;L&iCHzE9{v7oz$GuKmq0>A5)fw>UlM8O3>6U-)*o|95u6^9>;% zCFWTe4rQ@wHT<-_uGFObJeefe4rQ@xfr+@?_c~G?^ygs$Onpn zQHz0gAMZ!~Wz4mDLOxIoj9Luz(Ekhc{}TOQ$Onpn(Taie68!$Szhd0~t&k5C1EUrL zJ@o$``hSW3FXRKoz-YxldMSQ?-QO_o|4zsUih)s!fgbvQ{CA9b=>I}KPz;P#45a_W zGhg)o*6)RUpcojn80ew@r~km1hyE|*1I55-#Xx!)p8sEnasLlOK2QvdS`75i|4a1$ z68&Gu2a18wih=ZBxc|Qh``+ct3@khbH1?0~*sr!%+iT2R_?Ri5$!A+i z3@8UE2Pg(cHwLzpaZGk7Co2XP9s?TtM|bR3+pFz0W-ffpl+Wa|EhPq&1C#?41EU)Q zTgo^lJCu_Z0}GFV{5u%?2u(h1Uohbq@pmU&h(2^xH%#Yy6E6Ker}cvg$B2G7;kuys z(S*x>JmHd`Obor(>wY@n7)|!~P@Yl#Y{D_}pTqxz_AlUHLi|hkm(Yi<`qhN%{2G4z z4SdxbwmU!gps^E+Idkp3R^BDDU1IuoKlqW**~bj6?0_J2m({{?OR*J1n1 zFO54!ll{GF+%Z~T9e0fUYvYd5{W|_GJ0bqYxMO7B9Cy{Z!|&X8oe-|IrT-+!saphI^}=mf93z?aV#{xHGR)= zzt^$c?{zHqdmYRDUdM93*D3!i|11A%{;&DJ=Kq@iuUq$M%Inuvul%q1zvlnA&kZ~W z(EMNP|62bKKLcQE|6a$|{=JT^{d=9(|F!|9bw9by7Y5*Yp2@eGg6J`gPT7{;&Bzy9ZGI5AOlc^M5`6XM6v= zj_v*PI=1)E>$Lw*`~S56FFgOfuJ<{i z$If+s0y*#;u=**+H^$GPXZ##`#xI~}{1SS`ub^lA8hXZWpznd-g5QDP*X;iTz9W=> z#1%Tbt%h9(9ZY|pVKeaX=u)lN2q@x@LJ)w04VvErJFUB`QaV7c> zp??+ZBgC_?kI;@LUAon9n-8{s@!(0v=pR1m7}?g7j?vi${v-6a#rX-zc8EVhc70r* zP;8I5-yv*&h5o>3O-?#S0X-vLHR%`y^o)24e3gmH&g|7|s3u-hkwOuVcC2>saphI+pvr zj^%!@W4Yh!l>e3gmH##W*Zg1ef6f2bfB#?kAM--82EgY2UdQJCUdQJCUdQJCUdQJC zUdQJCUZ?rL=Kos%$2x%4|F!i#|JVFq^MB3% zHUG!`!94E)vUmTyj=lTmbz1+&{GGf5$lm?)IyU$BI`;0L*Ddw^zw#lIE=2q=z5l2E z|9lUi_Wxn-P2K@y@BVomd-u=l*t>sT*Yy5h{@E2y$Ono6#eiZ!F`yVw3@8Q^1BwB~ zfMP%~pcqgLCPV3?0j?ss{JPhYJ9LGHZ*8_vLl#hg-kUa`z z39U!tyo5e3h;?iiip#vLPl0_;A1+(l0ucU@4NFl>KzB78$go;2#$@@;Bo80XnaTPf?apei!xysJhU7 zFHH4)=zhQ{euy?Dbbf^P{qeBPgYn<~3H(Qh--P&O{1keE`x#<`(E2&zlaTxZ@keO= z66Fc;uh71~4%^@JIzs+tv_GNv4g62Ydnixn{1$OZD1L|Y6FR>~c|!gNwC^9o_P0)k z{|M1D;XgtbI!5s<)Sr+&8}Ughp(v!E(RX4fd7! zKC|5Kb)nqvzgPZ8+Z@4Rx!>zp?)N(7fA~oGU-^Hl_5b#-AJ16s_d1&U{e8htIV|^k z9n1Y*$8x{dvE1)<%Kys$%Kx|zIUIfE5y*#N@IHpk{k@LO{k@LO{k@LO{k=~4A3h>$ z0Br8>b!_hMb(;UfzncFK_4&d6ul$ekQ1k!b8UUO7dmWqmdmWqmdmWqmdmWqmdmWqm zd!6S0$gzhh|7-mpeO2rKTK})D11SG1|7-mpa|EpQ&&S}s@_e7Q{?FF{H2=pMB-sPN z=Kfx%`9GfB>G^+f9{_vy?{#|qujl`I{;%i%TK~s=iuV6$|KBr)pMSBve_j{b`{%#c z{y+Zg-|r33^MAyU_WuQ+18Dsp>kfy`kM{rLxdrz4F|_}W?*Y*BfAlRq|JU>X+H;R< z*K*0Tf4?t)?fv&Uw)fxbSnl^aw)fxb*xrAyV|)L-PW%7y{QDI6LHqx;|4;LO&HooT z|L?yJ_YVPjZ{Y9#`S$`t@BaDk_5L5$bx#pM>tq5OV=~ zFNf|GVS1-Q_exInD#SmbeD#>?bcWk}u>E>h<9P@noy9vOgzPmKUkK@I5qE_Abr?Sg z#p@Bfgw7jaA0dAuuKy-t|G-!{(J)?Zwgv%d4;o8SwoH`a` z5wN;@$#TEf4IVq+XO{cDE|mNI_sah~_xt+-mixVq<$kYI{znWe|11AnKC4TT`~7_Z z%l%%*a=+KH-0yWP_j?`7{a(j%zt<`MEB`D1YyPkKzvlm%|IhO~fRz9F9FNTX{ki~~ z`+FUm`+FUm`+FUm`+FUm`+J?{|C;}6{U7~A>;GE+*ZTkZxlZ|ieV+`jktqLD|FE@x zuVZWfUdPt{y^gK@dmUT*_d2cr>-oQ)|Lgg`p8wA?_xE{D`Jd)D_UvEt|CRLFzw*DH z|FgY+UdQ(S>G?nMHre~is|M|JVC}>>glKfBxS)4}F+1xEExe&)sjY zaE#V>R=5z=1<-ZF#NS)t-1j-r4_7$Kk5{<#Co5d`vlaMTnmG1Xuy??YK7OYB8hXZW zpeLli!}SU753r9={t@FZq4j6@k5K*v?{EKYh3ots*SQe#qG9_x7vnoZ-e2Ju*(LBT zp?fLfgOFW@@`UJev>74$H_8)wYtimktZ>DDA+Lh%R}b5t?27S=P(sIucf&IVLIE8k z-W}x$1$2x!MtMTvb$j3(Al?%a490(QBD}u>J8~ z&=We)F`^rx{RtU#j2`ri_Ko2mLIoY8brbjxxSQf#P|yd1@lSKVzb_cbmGgaOx!>zT zx!-@U{Lgd0zb|09-|JZJ_d4Z&<$vY>+L$*mrqSH*?+Zxo_d1sQy^iI6uVcC2>saph zI+pvrPWfN?U-@72f6f0j|JVF~{dWMA|26;D{2%lD&@+I6du7f4=Xn-D*8cr-0k-z< zb!_cl^MAhf@1F~>wSTYE`akABTK^BOV=DhE|11A1{|EN~uxI~Xr~I$y|9bu(+yfAL z_V2&f^M9@XvuFQa$DaLr9eeigb$b4<=l|OOr~QB0|A%~wy?@&OH~b7h^MB3%HUHQA zU-SR@-veNK|Gkdw{r5Vy_uuQ--hZ!Sd;himkDTuJ_Y<`LAA97q|3CQrgYEtII=1)U z>)76ZuVZ`vy-xFg?f(zG1E}}^wEtiEA9Hr{4j{|@UboczpFIw1)B$?O=>0$K|L6Ar z%Kw}8`+xE0F@GSGV=EmaxxI4?w~KR(>`U+up_st$SSGaZ>>MN8-8n|`1;j6*9Ebgc z><&0TA>P$FMyJC2rG(Zb{zf&ScNgavRqPxi{UX-?2<1xH&$y#=C84#ObBywM>KS6#YbbpF_XhQsR^j|{z7q~tl|0U)CzY6z%mixVq z<$kYYx!>zp?)N&D`@N3key?M>-|JZJ_d1sQy^iI6uVcC2>saphI+pvrj^%!@W4Yh! zSnl^amixVq=6-))Kyts=vE1)saphI+pvr zj^%!@W4Yh!Snl^amixVq<$kYYx!>zp?)N&D`@N3key?M>-|JZJ_d1sQy^iL7e_udy zzt^$c?{zHqd);7PSj^}Cp6~&ow-@>zA-eHO$B1u&HYT{6;{KEn?TzbuwwfR1f6f2d zJ%IB6{QbuIQ*w8VVTAM^$N_}%o*07((Lv5JTKC2nPe>2O7<`}bIH&xt`9He{Q2yur zKYs|;zX-*l&N2EA#XT?~c{s)wLUtJXH=#HjIXXC~t!PODJxN@`TRb7$5ct_kZPo<$vY>#rOa8*0{eXv~PnoFhaIJ`X`}t zTdWZi@&howFm8wX9T@Ka%Kys$%KwY+|MT4wY);=P|11A1|Br6}SN>Q2SNC!U zpcqgLCj`@_;-b56A=Z zfIJ`%$OH0#JRlFq1M+}8AP>j`@_;-b56A=ZfIJ`%$OH0#JRlFq1M+}8AP>j`@_;-b z56A=ZfIJ`%$OH0#JRlFq1M+}8AP>j`@_;-b56A=ZfIJ`%$OH0#JRlFq1M+}8AP>j` z@_;-b56A=ZfIJ`%$OH0#JRlFq1M+}8AP>j`@_;-b56A=ZfIJ`%$OH0#JRlFq1M+}8 zAP>j`@_;-b56A=ZfIJ`%$OH0#JRlFq1M+}8AP>j`@_;-b56A=ZfIJ`%$OH0#JRlFq z1M+}8AP>j`@_;-b56A=ZfIJ`%$OH0#JRlFq1M+}8AP>j`@_;-b56A=ZfIJ`%$OH0# zJRlFq1M+}8AP>j`@_;-b56A=ZfIJ`%$OH0#JRlFq1M+}8AP>j`@_;-b56A=ZfIJ`% z$OH0#JRlFq1M+}8AP>j`@_;-b56A=ZfIJ`%$OH0#JRlFq1M+}8AP>j`@_;-b56A=Z zfIJ`%$OH0#JRlFq1M+}8AP>j`@_;-b56A=ZfIJ`%$OH0#JRlFq16z;>;%okyNlESB z!Poq2U-R#l-^thf%dh!&>NWrJj+I!N-07NsRu8ks%A5b~Iwo2B`!Y){Z`ZNwtNpF#&q?ba<|k_p zwZBEo(&VU*|CWEui^I{^YK7x3IoOx6J`~T9sxA~VI_4aqy{Iiy{d|=YXr+R<3`LC5*thDP`dAp8D8z0sm|B{1SD74(= zt)5nYtEWjDuj}JkJ8d79ppe;TQ{29(L?uslNeR>h;zBa}i|zH-DP6_NljL z(w>VyJI>16aVA6UxS`tLu4C7?crh8ypXssw{!Q(_dAGl{`(mZqU+wQ>z~aa9sY&Jk zxeQ?Atc~ZJ%J^^XwpgkDul}$8AIH{z?0(MVrhflt^!*wLzm+p-?Pjv6{j8ixD`&E)ytTVYYj=}s|LeAXvRMCHIg{3ICY##N%9*rsCY#Dz zyPLFjH>vhl`}-KE=W&hy8vj$=x!HZ6NgFRr*5k(R<2Tm*pRN0wY+C=X-~U-TlTGFA zIFmLGn`~NtuyQ7?oXL${-mYWP@_zK59nhdq$hH8Jij!BCblTG(8OKrcUmbZ2@X?`@h zvD?qCYtpW3vg!JEoJng3lN-DJmo)iD;ib0UQp=m)O`0D~Hu>MmnY3~yH+Ffuj!A2G zlWPCDI{@>KwTJB=w01LT$C;BaEKezu+{of*IPFmcU+}QDB*D+~vYEu1Q{oltx z{eEmi-T$fotN$-02JHUL&SB%2$?*6&S7NEh zdizqv?B{xYTFKlI_55SUU)S<>+;YiH zt^b?i@--x9gZ(X#ClDZ_?teo<|PD=E-YcdReZ<$92uWRt2-yr1hJ+JsYb3 z+jTb;Y3**(>Q(oHU;i`RptN!(O?O?(+wuP^xw*H$jlU+%&*p#o-XsS6c9ej?KPz8X zTl`x;KDd4GVfADD&o=JVb>?U5S9`bio^Se8FSgNtwtCrxtbQiVA7;OeXB(>jU)wI% zRKVKJWT+nX{BP&6aweO~TYH%_`%GGU+jDQ*7h%8u!|q?~dUe@!eXF{t8GMS!)tNwxo+2kLpu z@`v>slh*G|s{hY+{9F8*-6luHezm{Ge;)%D_a;Xr z{?-5IMgVJflWPAt4{WOUKeqlbs?yd~Mpce#yUT8QKpv0>fb~n36wcX8b^TVi0^TVjhQEhj#dsN%q>^47)sx&{0svOmJH@io* z-OXCI0!>GzpZFjSKRNLL`uKU6Ev6!^=kotZO`~5vjEpOMc`q+LEll6TQwlCDb z|BzUr0crIyY3~Qvb<7^T|Gu|>|I76D{NL;}8LEfvUmdvg|9`Y{CKp=X>@(T4|FwR7 zv)iQE7qZ`uv-8+-Ce2@Ud({5sv0-U`GO6~Ti=etcEPgD`%!}qPlj{F`|F`+gr1fW$ z>i=^dusE~vOymDt{4oJjx%Y;Yy6+fL^cj-{?|G%M$lONn6$Vt*%Uu^oJq_3 zCY$oVl{0B^YBF>l`~AUIZ);a8XEI!VuE#93yw%(OPMhU7lTGt~D{s>3YqH6IR{y2; ze>;!W!=&1Ot|jX2VB?4RN$o%935#2kb-!7^u=_vrpGoVtCPU{@|DRhwwSKGqKbHY4 zZcK*bN8^7C7g+q5w0>w(OEZ@{wOe`S6%X?`== zZcR4Duaz@tdD~>@Ji7lIzW=lKlavSK z0eL_kkO$-ec|abJ2jl^HKpv0>(+Io#iw*KS)fPM{T%Y6+JD3B z|FO6=Y5q3Z6u(x^r1g7~)~faMssGRY{ZRG)IS*Kz)MY(xY@e9=zxuz=nbv>mabrI> z#gFp8jofq6{AE((KY#yY*n2zeWPUT* zTYodj#;?Q*4M-c$OxpNp*Rgqlz5il*yRRGW{jFB09@hV@yvc=@x2jwDh0g!2yh*d$ zq@6cpza3}g?KqR>FSE=1VefA*wY*)&u5afzsrKjj-~49M+QX#Uf6fCIXBN-u|9by> zL;U_1>t7~qoHQ94$1HzXzqRrj|IK4_QsckIe;)&Oe`fu|-v6@xW76`TN$Xb{|K~hV z&wu78^Pl<2q#a)$&vgGc=P`>fljbLrHk#GPF^&Jj@Bdi*nZHcd{igmu{Qi&m&7}2b zlNOit{%rTZcAS;B<4j)H{%_~8aweO~+i@nX-Ay*Nzm+p-{mx|QJbM3Q`27#Hzuy1y zF<|}3WK;jOes9vsnQSU=$CXEw+HK{Q%Wk{wV(qqaX2)Ws)nmD&*|Au;Si7y9tzSvX1M+}8 zAP>j`@_;-b56A=ZfIJ`%$OH1gmg|8iuX_EpS6)54*nhT=5Jh=ZMZKsWt&OgXu8wB& z*=n{o+n-%Kd*$rnPk-I3wXP!gl!FTNKp(6HSAwg-EYzR^J>wJ;$rByEdGAF54IY#^y)DMJWx;k%_qwEIz3GHvge}wq_RW8VP zR=MZ`!go>k2C6RVPbj{JHvfLu{_>Y-A40J^#t%aBEBK$_e!a>C`3+){(SvQjF_V1^9+oiClA|fb(fr?x!>Ox(A@9u3;Z#JQ118N zEB}++@9ztg|CRqYa{iBgKI0foV`LxYDZhX|K>Vv2*ZOss^fxmu>v8hm&NxQrcQdZ@ zdt3v#Za(rqpgdu|GK1e`e?6U4-is+{HLQA??pNMsdlEV^o*Ie}vvY;lInm_RnY2D1FD~{>uNjcO`RwuVZt6 zuM5uo{knkW|C;|V^ZdX1`=nzujfLeuCLQHM=mYdFn#3F+Onk|tYhB7o{yFIw?aL-z z`(HRmApa+qqdXy0?%MDFjdK%{wKzW^|IegjlvluigzCR&KSKA)N!Pt9Y=8G^=n2=_ z8Sq~ycAEc(+EMu*>to~@fbzfA|F`7z z|303FF+$^peV_dc&sPXN=t8tF$Ne>-^>3_gH{jOd`3fP2t`E}xAP)hnx5?tGxCX(F z3(4ebc)mh#Uq}4{MCYJRjBlWB-{fTH!vBQiTX?>KXMDl>{{ZzTgv#0XJ(OjXKScfw z@gwB!9}|9pvH7Q*_-D9(AVfb$i~*}}T}FR|e+c#C>pvGL%gFwO_6d;w8TI-L;jgIM z-#A_98O7fb`~L{rul%q4ujl_5qXK&XSnl^a_Uzy5g3tc_z5q7&_qzYV^Z)DvQ;ty| z@9IA%ADnWG_(OQc9OA=x{{E3L?yM=-Z=n0pDaR;FJmWlj-P(U%t^4e4X@87Ux3~Ut z{BhVvh&}=P2=0^EgUI+4^n^ZijP9qWT=AK8HYZIN(=)v$Wp@NQ)KLqt7B!?nC3DHAweL@9Y{xD*HgMCfyzq#v`|CRrh z|3^3fZ|>ul>aX0U7+8D^DE}+}EB}vf{&yE*eoAN>TPu`hWEWxn8X&$HYxjh_k8$l1 zP7iuU=Tgic|A{qnP+W$!{(migtZeed=BSS@$NZVlWK$Pq8Tr34{|?Yvi?$~h2 zc8uJucG=`=m#$jv+Ec4tvU>HFrj#_`ond=!)BO(mSAC3Gp3KKTzBW z$K4s%y34Tref-R5vcJ45;**djxNZP!Q|CRq~{zpFS6Pm`q@?gX$p?x3Ra|P(*`_6sCwC;!8-avML+}je|15iKEejw}w zod+rZH?`>~>6QOA|JVFKyav!T7O=U$*M;W({(H^;!*hSXF7UsY|2MVomafw6$JYM6F0}UVzuy$r|C{XF()G&!%Kz*hpeg>f{*QIF9m0g3 z{rm6r{2xBh^Z(!;06qWb&;I@10QT(P>zbbbH;r#wx?cHT`Cs`zyav$J|5@($I^}=d z8wK_NYX4t&@1NfnsQj<|-!%R#Rj>T7{IC44{2zJ-&@{fVz5iYp%KiR(<$vY><=+3_ z6yICAUin}7f0XlojCcPSP5r+gA;%HQt+4+#K(;mZ;%*bB4_&z}C%Yc@{}Ni;p?;ve zK91WS*TR~_kWJJ0nbGk3k)kzt|Bp~X7b4#Y&)s(p6Wsu18^~{n_xlLRE~wwGI1k8o z!?kuFwx7NG=XFEAn#UK~|A+fH@(!S$|8Ls)C4VdW1tESLo}myb=osnS@r;HLy#xJ| zP(a5>-iba<=s}kku;E>(CrHm2?$hZ%@ExIojuBsoa}#pt7(M72$wjb_P(a6sE{1)e z0&yR80fS>&bSC^ysGwuy@5VU^$$Lk70f}YTaj?w!l+Mm!Z@r;~MoekRv<;M^oAIDzvPr&|9;vV2r!}h12Mtl%D zpFvqd^;uk>(EA+hBSc?-{|NCH5x0coOK4L<`eoQ%!3SSKJ->>&d~MkN=p0<1(1ngs zd;{kuq~C;p3GunGkI;jTQG5&6C#2`${NKhoKyg0m@||J(;|riC^r2%^--TZZc^CdC zB;P~(5u)#-eFznFjQj^U{||AFAK^HV|9IH`4> z2bmixVq<$kYYx!>zp?)N&D`@N3key>yhM;ly> zb^^-(h!^Gmq5jWuzt^$c?{zHqdmYRDUdM93*RkC1bu9OLo$^0?sQe$y|HW^RV+idY zp3xAZ-y((yC3KARcZgAf`#tu75Gv>x*&opUf5bfm$p3`g|7Yd@!TTRJ_xCzB_xHLO z^LIuLJ);LbgU$WDj?MkOE<)Z{{zp4%{;&DJ=Kq@i*XI9&xnLAOYyOY?h&&!b`5(FS z%rI>2-|N`gzt^#~f3IU}|6a$|{=H7?|F}og`oGrywf;Zv`u`~A{6U+Q|HHZ8-xDbR zhjYKbFHru+J-78|F{C zJRXA0{gwa2dEf2{l>hl206qW5^F!_b3+@4Ad;h$S?fvt*ru~1TnDYm1R{mH159NOU zz4AYD{6`36?(gpbl>e3gwf`S^IPeYt+xzcz%Ksbp{Xyk_<$vXWj58k&z;eIWDgV=V z0JQ%fzdU1g=l$LB}W_iFy&zN5MaY_|dpNp$A=Y1kUjo9G9XlV9@^J zvCuP)gr0E}^n}jQc!!RVKMwvUWRFMe64GN}8=-wH+Wt7$`~=v4Jl-XG;;{YE35W^C ziO@5i1U;b-9ix|_O$gm5qt6nmr=Wij%9GGOPemI%4Ss$)eEE!F`_q%*KSJx7IGzwa z3-%K#=otC4Q7=OB9JC)HdM>U{sG!SF!8x9X<8ssm490){eCP@33*a9@@OB&XrLgg$hP;+2R`Li<%1 ze+kj6VH2T*F72S-zXo=K?6t%8v)u1>EcbgI%l%%*a=+KH-0yWP_j?`7{a&a1ul%q4 zk3O&bul%q4zh3^2Ux)i*LJvAd@p|MyLi-KKfrRLd$bp0sI!5{?`mU4;2NBZZz(LC;`wf3MU0A8n-hzw*E4|C;~LGyfmV zg`@ac`9GZd{e6M*zt;b?{*Qau&@%w6?`!=ZJ_tMmU~B(g$JYM6j;;NB9b5bNI<5c1 z2W0(!6m$Nd&C37E|9bw9HG&UZzuVc^ty^cNm_d53M-|N`3f3MT?f3(q4 z(GHsbYyPkK|IpgMzYkFUSN>Q2SN;#~0SwLi?R(AtgL8ksCZPF0)+jdN{eOdV;Zgjo z{IC44{IC44{ExMidENtHd;h)8=Xi$lzw-a4d|#pbul%q4ul%q4ulzsXdw}fSKd)o& z{&^jn`+FUG_s{FtyMJEC-u?5sruY9g<=p(gs9S!-v|}{YA$`m=-mNC2&;{r`b{g+i zhv^@E(f*luX#Awp91>{A-nDS9?CNMC*k^prNhqEH{}8H^r(O4%Vf)j|Fzyq~ z&X8>X3(wdYmqSm;|BW$@P_D)MKaBrC&$t5jHvb)d=O<)~zTddNYi(2XZ*s*d$7rf^ z@!wU5uQ1t_s~jV_3fCvNt5-Qj4|+y9yUOL!lxuG_<>IZUTpu*qv=Dv&+c+m-A?KR! z*!KCTJE035qy3#JR|0pzl*>T<8r3#aj!{3p{&Ra<)Q`}IE=2cwQ!d{wO#Av%F4~?` zLeEHdK=~clx7+OKK*zA-LNZ=~xFS^0F*;+oJ|P{SatyZ;ZA+-2ODDqi_n~8i?6&VS zhqxlRNz{+fgN{+ILi-ZZDcDDFt5F_UeI?}!#lX54V7cGxnta7_zt^$c?{zHqdmYRD zUdM93*D3$={GZ+n^G`xk`^N`OJBGVA=Dz{rgQ2@mnE1ZX-H#L9AM;m2AG+=X!t=lK zfzyuBWPko3%ufkfd)hHNhfF(0`C!zK@et@4hhl#G(6Iga!%%-hll{rVF@I+q20bA= z9R48`k3jtykA$A_DERl$Vf%Z1JpUmy+J6bwAPF7l7(M72txGX?C*;sEy3oh}#Crsw z0uE~(O*TotE)71i>zd~O?%Bw%gr@qJD9gy7gZvWW zxw!W@h44I#+d0QQAN42np(|ey9{;l!BL5JY?2liB`yWCdI?9WoXS@V@LieS(zaf;T z!v8M|+n>A~`I*pUe-~vL#Ve4X8K*(dcqR0N>{Vz#Li^Q-k51VB&Xvf|geLo=tMH7G zkU_`jLC7VH1OMTi5?2Te9fzw~i?bMc|_|I*rebI<>s128`#G{tfE zb{PK&$?cI}0`%^H+<&Jq(OocR-IWvF4fB6Oes_#{_Xv-9)oyDXqsjjGm&pHwrt(et z4$jSpeg*pp8FXFH`Zdl2>enm3hV>yr{rLLN={9ITLjCyq&&k$^4??;v&d<0W^n`3X z=&!%N-ByqM>v;Y|u;W6q+yVEOgityAzP`G^!)cX3)Azun{#^5Gt&K_2O&GsTj2bJP&xa) zhq8?HmN-A52OT4Ap**1n9V5LJ^uX#{m+7r>enS2D`p-R-Wu&*k`3XJf80r2fPv}9% zNN)>0sMp(m&URnp7q!-{MVVp{F0Eb#QF`Psa~B`I6q?wdP1=p`e`r$ z+=ibA_jktn5+R>~{e&j_dpE%Q6^t7~&)5a)KfA*AHF!^Crwwm^Q~jmiH2bZ!i}L@{ z+DG|+Y5ub~TrTPM#{6vwq~FE<^8j7EZ_zyf^Sc14|9&fs&x8~@MjvbXy=UQ=SI@ZC z?f}2jG2LUvMOc^V$8$e#Oy8F0;`sq#$=CiC;)_s1$7r25Q#=B%-|gu zLcRv|BNRK~-CIJn^D5W9LD>G@4N-qWcNdf=B)g*igmgEwAEDeGu|tUVSmhY4Jz*Om z-3$J^QP}=!pBcwU9*y6TO^ElMaf}Z1A(ETn+JyAxGkCVeN%xy^j2`suTZHceqswux zNNDQ+eUxQHYjOSn$$wC{E5daCJL8HgIptL|j!|6=AJ2yEuOjUKA(UI;`3oW5dJWzy z57XKP&t3@mwrd=tx*qCB=xvARTZCwP%x`uGKmUn$MBNE)1R_v75WAvN8e|}w?zLZbf627v~X=gdaD`NZJ>Q?^dCYOy5u$_ z{+0ig|3^6g7w8*|{0Q`aLUCu5C$#T^{uv;-D{^BJrUzZ;Zk*)q=--6s9;hD(<#Cq# zy)IPFzGu1L>q5ETf3N({bHBeYV7cGxSnl^a<$s?4)BSP(Oei0N^+iH*PsA~y4_%1f zz0fxg3X|U({qJB-4|+y%AJp%@;eO2K{$6MOJS5rN-|IqifB(Ja|9tN6*9F+z-|N`i z-|IC0=kx#gwzz*M^iuqOA_n?akC5GO#)U}kkFtc~0qDCA&N-|N`gzt^#~f3IU}|6a$|{=JT^ z{d-;0`hR`^`Y$0q3eWcmUGyzR`(fyR0o=oJ?@wqShTPsjb~x@Y2+<>89|+yQEB`D1 zkMjC|>vrfHgyd*E|0DF#w;1^&(fYJ|p>Hv=$K(DyKR=XGrF zpVzUye_qG-{%QSxvD0@PfK6ITEIjtw5JfRC+ zJHs(}FJwNH|CRqoIsf<3_Zii(cz=e_Mc-niPsaUsfcPoM&4lbEJiB`;rvp7Bej4r% zz`0EB`D1k8=J`?}+?NaL41_Swi$2gzo>9 z|CRqoIsf<2_Zis<`1_`W{8T*OC$wIMz84^VIj&8pUV(F;#z|g@`+q|8Dy%VpQ2+1! z0{KtK2a17_i-GnpSGmrGt6VJP1I56|#elmA?~i=|zklZpAs;9PMlJ?Ej{g5a>`_7g z7xIB(V6u%l2=o6lg?ykG7_}H^eFEbh`hWCpAs;9PMlA+P^#9I>G47-P3;94X zFj_It`XqjT!bdRfzemUiih)s!ffD_{i~gUZ{|os*F)&&&(E1eKZ#@g+{(FUdpcojn z7%0*I-A6Izq5li{Krt{{G0^%ne*Yr+fAl^fA1DS!Ee1;T|8|Kn5B*=r2a18wih#lWb=K#BfeqW|aU|3W@c42)I`v_6Z!kMJ?90s41zEF|Z|#WwJ%NSuwD%7|_^1x?{iE zUTv@Oa$)18{3U;FNim=tpd6qW7~L4ylEyOGqTH+)SXc~b>>u5+Uv00p*Lb0i_nLz`-$N;Z*0?n z_-;D3{3PO+P<#sgmr#8gu}SED2K6UYpGA2>`8mY>=Qp1H*%vVW5ZYfv|0JYeLZ2jL zU&i?fX@&BH_E#|ee>H4>c_R7%p{f0=Cr>#>dJ_5`A$l76B%yfvlw%|(PdP^KnHYbb zjWOi8sOKrDOFrEHS?>3`Ci_|L_qtH-_uni3^W5+63s~;=I+pvrPWfN?U-`dz9BUfq zLVA|_y^iI6uVcC2>saphI+pvrPWfN?U-@72f6f0j|JVF~cb!_hMb!_hMb!_hMb(;Tc{a@?P5b@7c&`~3 zBD;y+|5N@~{@t|f&4V?UqGkE_$ zO!lT3m%e$%wcj%1lG8C>y%h}X1B%~<@s06z=o#;Tp7BoT83pu=cR|lM1A4}p(7zkJ z2fP=&uV(-I@g2c^V8$_`590lBLLWLt??Z?mLifXnA42t!8OJEknsLQP5knzQH(29B zw02tK(vPEm5wcIf=K;!3qHRAF#(f5L{Vb>bIrMEp_Ib4X7lv&fw70N8EoWY=8Vi=m{O@7}1Z=euNx4M)YHpC*;sEqMx8VA@{nU;v69Q z86+5r|5q#jEB~Vp1nvP??)N&D`@N3key?M>-|JZJ_d1sQy-xWbZL9o0H0BMBf6D*L z|H}WtHGsjsGT&!5_xHNc+~0q%`9H>HHuv{BHuv{BHuv{B&Hpw3SN>Q2A6WAo9LL$* z-|N`i-|N`i-|N`i-|N`i-|N`i-|N`i-|IC0*Zg1W|F{p(`oGrywf?`}eE?ni_iF=W z?ceLz+P~MawSTW;YyV!y*8aVYt^IqQ*8ef~Y5ia8|9bwf=l^Hx`M;k355Lo`{IBQ# zdj22Y12DK&G~Z{f|Kt8r`~QOb0QCGHYnWsYAlv)rb!_jS*Rj2SUZ?$km?LZd-+JpF zHkNDsAALyA|MmPo^bP>q`|ouu_j?`N`|ovn{!jM+YX2X<2T=aU8oBoW2cH9I{U2kj z*8jEsul0Ye|7-n!!SDaMHEUdmd}qD?r|19JgQxfZg6{ybcmKSOz5C~N?A<@FWAFZX zUDNx2ty3nQkPj3CiUGxdVn8vV7*Gr-1{4E|0mXn~Krx^gPz)#r6a$I@#eiZ!F`yVw z3@8Q^1BwB~fMP%~pcqgLCjAo|r_annp(1pm?;MzNdiFQWW z2J#zBIYx3r)NL1>2jsirTDuMZ{_kja=m`~cj6BA93CSL~CL!7r*C$laG4j1|eL`|0 zod3o+2gq-Ny4rw=`&_hz*3TZU~OZ2#hP_>Yi1 z0`bduEA)i)ZHNy-{&vJCq4N&JA0dAy$`i5z?fb5<{jD>gBXl2$_9ygFmeD;Eu%^jcSjq5;vR_Adk*`8<$kXl>?`wqX1U+%Lb>06ul$d;*^|R^zt^$c?{&)m@R9Pr z^8Y#Wk7X?PdmYXF{=VR?9G3gNj^%!@W4Yh!Snl^a<$vXW<$v6V?1H|sEAruP!{Y#( z`+FUm`+FUm`+FUm`+J@8KYXP5e{c1cRV^mG&zz>2!!NF0fLHAP?};CK~Th#A}ESSQ&h@{sE8;h zB3(ET5d`D}RGP{EJC_8Kb+h>T{@?fazOVDdk9)h%%`!%au|L(x#r{+$7yDBki~m{t&*uNp2e!gkh0Xu7`F~T{@vq$6Kh>2t_fLg&wSQD6=liLS`G4mB+5CUmIiJ$~ zx7^%6)v@`1w*Ie7eG#prVg8@_f42U={Ow0I=`> z$*%!m@Bi8R|NrFg|K$laIXUEFf2wmTYs$i_YI5Zfg3hllpL|VCE9kUxgUBz3&r*|k7p_kRKXh{B^+x%9P)1** z19|<*-apr|4kt(HdzJd^=~Rc4!_m18CkH3s{4xZglf$R1!^x4Ss>3fQy2LCYBI~jt*(SOK5MxyS@5Q0vQ;QcuND4F{&)fYQiNkzaw5vLR++F8A!W2TmX3QML*RZeNl(9?O)FKQ{CO}pZS00|C#?U ze+(e!`>9UO_fwsm@25IB-%oYS|1f~a7s*{WTsZK8Tr#iXVpX%gdf2w2g zKa2la{Lkk9+5A77|7Y|65@P`7|K(#`nYn-ZUO;Z{pX%i1{;5uG?w{)9=KiTpZtkDz z*!(}6|7Y+2(N5U=fA;>Lz5oBCuVeoIk2Wdwep~L{KlA_i_X%a*{j>T1^4I>+HGypX zAI7ILYyYTDZtWk{$*ujPI=23gt^Z@||H^;=OXv9IVDtZM{h!<#0OtSUqh!7VP~O^q z=KqVn7r^{KTmLV&29T})gYTC44uIU+f2w2a|JnL~w*H^3|7YL-W8eQ{-~ao^zyC*` ztihE>a4!4)A6x&&zW*mT2k@W1{$F^e1}97DcR>=L`TQE39C^>y;L3xW58dp|FN3fK_alSvO+25qxc9elo^{x+FMI#_8*og9yp4E1GI%!O`{6PK-l@UK;n|G* zGLZM-e`N4{fc!E9x8V6~!*|@bWBXwZF1VxY{dg0Ss)yesOs+05mRLA^3^Z(5Mi+opX%g%Kh??keyWr6{Zz;NKWxb2e-{6<_@Bl9rTYDnIRM$%pUw-&#Qsz#7yDD4 zT z|Fif1a_<1x{C}-7?WJ_=KtIc^{iC|_*8b7sZ2cc>uv#9uwSQD6xAu?f*!n-bV`J<8 z*!n+-xqsS!G5^o}KlA_aBjv3FET`R+j02eehksd7K5}dSsgC)7yyIl+|I1wm$kzX{ z_5X5f0NDF~`F8+p{-4eNv-N-M`+w~Ff0&E=3*Y|>w8eM)%E8f|egBWG|6||(llu<9 zfBO1=&$ODH9HG7VH;!e~)aB&xpTfU+B18V8 z__y(82nBHeG6a6d?<>gQ3F5b5We85kZ*<9!x4#xAha;jcCkJ;LzcDL=FAr;+We9zR z`Uo^z(3za^~?8ovX;4w|_a`Pjzy>pX%g% zKh??keyWr6{ZuFC`>9UO_fwsm@25IB-%oXNzMtykd_UF6`F^UC^ZisO=liKn&i7ND zobRVPIp0rpa=xGHpXy|N zKOGy$_I z{FUo+fhvfPSo|+J7GVCL#sB5CjX!fdRJSfC2Uid6TZV-CXx}pU8ej}5L$D#{-(=t# zV+_=!{PxfMKlA_0|I7P$xqcvYrVjp%u<{A~fcHZ(gw7(b4CF_|XflMLlOuQ@b8HvN zk8@c3&*uN-<^WjyFW)!#e!(1)4BlVy{!0e`Z)l$~1g~L^ScbrL^e=MU!1diMzx^}+ z&-_30|MG2I&j0_n>zMy%{-62(zi<0z{-61O=Kue`?VtI7=Kq=h|NFLo=Kq=hXa4{1 z+y0sVXa1l0|G#hhXa1l0f9C)HzU`m+f9C(0|Nr~8f8X>P9D~__)d5xqSRG(>fYkw3 z2Us0ob%50YRtH!eV0D1i0agcC9bk2U)d5xqSRG(>fYkw32Us0ob%50YRtH!eV0D1i z0agcC9bk2U)d5xqSRG(>fYkw32Us0ob%50YRtH!eV0D1i0agcC9bk2U)d5xqSRG(> zfYkw32Us0ob%50YRtH!eV0D1if&be&Kok)Xk&viji55xBU4$@U7GM@&7GM@&7GM@& z7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@& z7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@& z7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@& z7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@& z7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@& z7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@& z7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@& z7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@& z7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7GM@& z7GM@&7GM@&7GM@&7GM@&7GM@&7GM@&7Wms(Ahcb4t1m95@|nGyRKi|A@TY{zcgMsFsm)`ewo4dcv z{^G@7mDx|P`CXa)2A#K--gj)=b*l6}$}e+%GWDJFrS-U>;Pz5?=&1RJxrSkKI%`TVLLsfLYt@_loVaK6Xm$@GA;>Cwcr-#1G{UM9Tf&bl+s65A= z9r`Ju^uB-3p3`N@TUV=>pQeIr9Z%dOlceMSX(WsAWHgyV9>CU$Kb}Zyi?SB|KZ%$~ z9CD|VM3O<0@F@%XV@N8QO2!fwnT#^BaE3%2O$n#-;7mC<))D(taFpiDgeDGUWaBtZ zIRPcb-`Djke=Acj?_9(`{i&qflKU&!{`rDS?z<$% zKij{#6ttu~JeMMlym@c<8PyG+Aa8sB*WN%|E7H-=FBTmSrzuKXk~ggQm;7(`tXWnR zjP`vleBR=d_(l6T>@U{m+5a`|D+}!@>#w#jT>tI%P<#s-)M* z26rHH3gZ-Q3N%qCZ@pN%(%_C{X5mPMso+ZF=-2Zd9u){7*wz}^62jt?twv_ z$rFXW6ln!Xkq;JhtoEt1GxQe4?1Flc-xX-8RK)(Q!p@4-1-m0s3x~$?_jMw33!5o+ z7fg+~RQOcI8Us6#d4)9;7Yo`&O+ndJAvisXgJmIZ4aJo%_Fi!>)Y3xA3n_WNVD#$-?7 zgQO?!${e-qmd(@Vy?#*yBIc~O;aoi)}c#|pJ%E~!!YLDZa^kL&A_?+crgH^}jV zi%~6aR@2rd7YaG@DOp!gC;GsRd8(S^YT@sNr^xIAb+q?Jv{0SgD!f>DgCrO9iq5++ zsbf_VNxm)Q6nzQ?Md#f3?%v9z64_hWQXv!!j-GbozP6PJM?NgnDjFB`jb40XOREZ` zF4Cl9^}E@uNhE1OUMw7~ zh$%P__3F(x8Y)Oz@*JLc)q>ZeB5yhB6HyH)t{DIBjf0->LiDDnt&!IvMn{}bJfi5V z2$Ah%5qwPo=}#>G?kmFiqCgC&2x37MPz`WEN@!Y|t|U!ue5U*>@W_bfpp*jROoZz0JSd_y%Ai^AtSQn6U*DXDlwLMn3g{!#e0g2B<-IWj>) ziq3N9|5YJXAeAApkV+7GNfjV5kZ1_K+DHh!D|+L1a{uv@A|fiLVr-RaT+Q0G>(y)0 zq&Nl5MzhmmXmPYyT0A`sJsmwQJw3e)dO7s6szItlI7kghO-LDZu?44vF@8(Z09z_zGDAB0bjy2TO_5QEDgL z2halvAP;zf9|QqfJK=!?B!E2N1%42uPwU^*AE0ei3{w%?@Lxsz|BlewONCxCmHfL3 zO@;J-vLCtKcZ~H+$@>#R8|>ZW|3|+<@8Yit?R==v4v6+Z;r<7G54EcF@k+6kt5mH< z?fl0)#kv}`YSSL3_?i^qo(*MFA2a~;0^I=hmDDd&UldKZ=pg=Cq1XIZ$|%Ygw!@$8 zf5PV}n=bpy5!v<9sFg;2+>1O6R|mKB72%B+`eoMg1{f#VQ zOq`Dw91dqf>HPm|pNDko-i+Q;uO0)P{f7p-UJ4!x3At6sn$V>^D zB_XpVWR8T)m5`?-qI3m5_cC(qBRbNXS45xlclz5;90a2202g2^lIO!z5(5gp81okrHyhgp87q(Gn6T zArDB%gAx)iArezt2`&j4BO!?rk|ZH+2`PG?RrdcW5;9goQYB=Zgp8MvGzpm?A?Xs5 zAt9n^#_;Y$3CWa@ED6b$kQ@n_Bq5U}WQv63O2||Rc}PMYmXJpzWSWFLDj`x+BacbQ z;}SAmLS{$^sc@}urAS^A$tsbo7Rl=(c|#;?MDnIc-V(`Lk-RMupGek;WW7i>h-9Nk zHi_h&VmVzb-;3moSbmU@vl1c^o1Ob(Y$g$zotKErE=WXX7yn#jCJ~o~B;vB4CE~Kn ze~il{qOz+JQQ0pNQQ5D5h|0tvnK&F1hhpL|OdNuV!!L2@B@Vkv$6ECB-D0h~#aMTX zt?m|6-7S_9$5D5SpY9en-7Q|aTby*a_~>qN(cR)9aUdiPgTx__IQ$WZKH{)P9P)_6 z9dW254s*mIjySv#hc@D{MjXJP?Nl;;=v*5{SbAaVQ`T1H>VK zc=#_K`iqDC;xWH?xGx^+i--B*A-;HcUv^ZVoGc#Ji-+{$;k z9=40e?Be0Nc&IKOri+K@;^Db?Xf7U>i-+Xm;kbAxE*^%9hv4Gjw|M9+9(Iez+~VQ3 zc&IHNW{Zc|;#U{q*B0Ve7UI_x;#U>o*A(Jc6ynzt;#U*m*An7a65{s};#U#k*AU`Y z5YLNbfk+mL%qli^-HCKJX{aTMJjpH}$U#rK_Ek(Flmb~lrxYCHn ztZbiIfLVZ9fLY*QX8{@~(^!$lOEhMn<7PT`q~oXXdJaKhiHMA@9;L2xdp%j#UCqdp zV-J#x!-kSulO7=h2Ja`oobO784!cFB-6y5= zjTL3}G)-xJQJ$jmM?rT-KLx9ZOa4yY{#112-@U(4bpC(${=fTv|I^M_QV;%}+l^!+ zIY~MwrjUJj`ZKZj&+J!Il+7>RpCT&%pTE-(dOP}8Qqn)VUy|?tZo4nso6z&G4By4c zGW#3xTxf4oq7UI|mEKHU4^$rh6P756I|<0(@;-7hJxn%$zNkd$)}<%-EWMumi$dAbq1Q^ubl56y}rApp9%XF{ZYG~#8uHf0?dj# z`zNtqqNgo|?o&@)lKy^0Sv^ftT3?i>DE&g{?&#@r`M><@p!mQ2`@g*R|AcdwJ1{I( z^t(#}vHl<3zf1A|6>9N!`bzKj!-$Ulm56wseou@_YWV+6!rvSFckcV&YRH9vV{Jn& z0Qk2Xa(N&K1YbkW2OR5=26)yt`5*weZ;>AOfN&gJAe_J!2tjN? z!b#i<$UB9yzQeVHgwweG?{Q9$a0Z`$fF6*u*aC76TR?t989+FX^8wEVobw`%0q0M+ zPT;$Q&moixgr89+;4ULS2!Z@7DCa8jf*^4Ig0w*R6={L+8@7PEhCCny60YNXz;Odx z;JAq`NVo+($on1X3y=>u3sEk}Cyh9wXvF1#An->t;)F8Nk~Zd7GdN5Cs0FNW^j4Fs(k94}?dt1$lY( zxgc;nR-f|%@_2nN0g&m~0_O~r0k|hn1_%J*No;{I6US%aI0yh?Hp&Dcx}Ae92+l>> zPoZo;o<^C#Pq*{11>R?HJRkeO5BO(sO@Mz6TaYjx#{vI5_CXLh7GMh;3vq3Le*xzM zWD%|f1VP?noF62-h-(9mmyj0lOOO@_FXP;RTZ*(G1QK3BTHx@a4B&hf=LW(uqy^k^ zqy-_6zXIo5iSvOVaK47LKv;#ez_A+V1N`eq3&#+sg2BZhVMwAB}n~)xmcTgtq)9t(10)8{D83cjjJ){HVeQW{w z0O^1q@LP}$1c75Kw!pCs=>XY|bifaIKhgpILu^41ICdZ%ARi$e@YC&1Yytl<(t#jw ze1dd;_EARX`n{tKi7{Fm4QVJ~a~Lcke-T>$qL zwt(9Qn}YxlzD7C_0?z%|0_QhK2e<=B2LeDih;%?Wge?dG=V7D++!3S$0lGbkEf9_& z9S8yEw@3%Llh z=Nz01gn(l%j)Nc&p2D>}jdK9cJd_W(XRrlaKCTz|0C^T=051pu$8#tH1OY!E=>T~i zX@D1mfMWsDfB@hYq8vb8KpNl$A>deq>ji$0uo!6oc@b%V7leTD60Qw!OOOV5K@jjS zV;|&$0PrkDeh>n}E7%7<5CXgx=K$nYhjN>2(eD7iZedGsT5CV=5a2)VkkOl}_Q5FaQ zejDinN{2&N~p2!aZfbWI;zz?|I$Pavg^g({$1tH+*i~Jx6gnq~m0)X$2 z{J;;m0mu)0z%dY8%6&-hgdR8tp$rfJ34^hv48ifCC>MB!Aw3|&kq(d%U?k23xchM} zAPAhJum#T1AP!}Kga>e)KzI=60?v4BDG9h17t(-)F(`wQh;&KVQrx(QWSkc`QgANH zSe!2vTgo_G!+2Z|;L}hB@B!xplu1d)=L}pA@OYpDWFn3MF9-ogCh~(I5VBAv2mn4C zd4L~qIVc#e1N=!>j7R60*)oP9}on>%g7G`fM1IIzz?`rkRSK}@ghI)f)H@L ziu@o5gk{JN0)StR{J;;m703^KfUHD*-~}Pzcn$eM5D2S~9|Qou8u@`AaIYgj@B#7$ z@&hjj0mmBT2SFgbiToe{__vTBa7WNb03RSn(Z>KU2m!}2^cNsVx8Gt5gyZNlKmhP3 z(2oE=;DRUz_y9SHa)1|vfa4Ul!0{c*0YM;~MmZn=`0r5;2m!|#isc^n6Rz+FK3z;_Y(e?mSGqT5T@0!Ikf0D?gH8D)R~;4h;L;0NRi z(t#ilt|AQx0R9)G0X`4{`M)9!5Pm}%5CHr&*a3Kf<2urSAP{aK4F~}4Caw*Hfa4a9 z13w_YV;^{c4>${u9|Qnbh<%U`0)P-aV-N&+3OvsU)CG_bi8>Gk9SDK^Xruu`4AOxB z;3}YwfDmw0L>dqTLM5aDBoob`|fvq2mrnzjswyNX#m$4 zWdR=`O^_G(fzTA?0tb)uAP9tJC^>S630OR@U3u9zz?|AC>!_yX@jx> z*A~Zs50G{^2D~5y9QUG35ClSdlnDZW?|?FaA8;L!AB2FT6VihqaCSyHAWuLZ;7~#b zf7eM|6#77qqFM))g5I@w$ z0gh|P1M;q;%o`{ZB-}(Ekbet#en%eQDL|QpC=)md+6~B4piM=feSm~W)cYv3E#Qbo zI{=;-w2caAFThz5Z3^U9LVJrv9*|HOd8!}}a8yN^Ag>zAtd2au$w3D~z)=HvK@bQv zQ9j^n;T*sZxY{TW_yDPcd>{lIb&(GQfp8DX2La%zhkSsmk9@!fNCTV`c!8rK@_`@_ z8X+GD0KPHu0x52sn7;141+80|CG{M?T;OTnpp_q$TnJF9-ogE1VMq zL0)U*1D-ZW-xleCvmMfb{CiP$d+33u1N0rC2hL8=gZ$3W3(y0P5_%Q%z^R5F|J@E8}z900!*&lk4KLGlH&;!qX&^w_A&Oy+F{K3!NrXNLdf;?J z5Au_tPk|nI#zLP8J#dbL9^{XQJ`H-{nE-t{^uU<`J;?V!KM{K1$%H-&df?249^~gh zKMD1N39|sR0J8wI0J8wIz&~Vxg+hhN9bDCZdVf%*#r1bisPN3yaUSi;#B<9RBrR3V zI$CYT=3}`{&V3V{b$H(k?fbt|Y3sx5rd8;;`G;p4Z_iKS-feuD_l@g4@x3d@yKI~B z$o?Y@&Y%8v!k|t2uYUT(*VBhDN~`5xJw9pb^)bI+_{=@$zBong!)Y;ziPq{jeyLjV z>0Nxf`9UtV|LHCX-(*fqS@zZGNK3E%QT={@qUyf!n_^eqSiMP`wrG9V1D}0x)Ny^w zo8P4!Qsu;*=&`rzfn)buzgqLAaJaRJ93PZ7=-{rpuE6$9S2s3mv2(-l#S7lwTYcr$ z%}X~&w5>QRI)44(Dxb7GS9#schci0Y=s$Mkn#QgVtsRr!$?tM(Qq07oiY@%UMfY;w zT$=sFx`|CUy%V$Y^!8WO`!}Cm_F07~n(L(cyw#N!)>~BV-aL77g=T|Fk zUOn*jxO1u9ZXHh7^qiIQR$z0&k*tnU-M?=fsgCa-`^IMvSN+y9G1~b?mxwkTS9#l$ ze3j2yZ5lgb!xI^NrTxk8y>i<1WwqxTOutGcn1Id1E_ zZ>7EO=cjMJ_|AsyFIGAAPUMUG)@2)eee>hnllQ$`r}fdO>2;4~)vTQO-3)Wm^R{sl zs;(Y2ZffPd)lR=$SZRKnwIp`k(h84spI<$+Z+XR;V=pV36zqseePG0x-#$-q=S|e5 z)&C)8eEOt@`wN2Yzn(p6>Je^F-)~bgPP}*h`lW62x@~*+o^R&)63#9^aA4Z}uU_4` zPL_HE22dq3U!-bdP3J=DKp?AyQgjnpMfjq38zrGyj1PNb~9 zG%sD5yDhcnQyW~LH<+Hh#k((~mG0Eo!3!o=*%R5T@(1tLjcDGvb@Z@p=J!8tTY2mH z=SFR8A2n`6+^WKZJCu6^o8~S(+@bN>PW<=TC@uJ*LtUyRO># zCsHb8)*3;gAMd+;LG7uVPpxgg?jb|NcdEQJZ{KrOw|(>dyO)kV-0Z~B%KP_y{bbiu z`+vT+;oGt4(~mU$qVBfGMz?V775 z?U-v{7mj!J*qc^&%BfiIPy4DK96CK};EoNEMpx^URln6u2n^_z+UMxxbX(tXU#&eh z>cHXT$|oEl^CA6^wOd~QcrNcc_sGo5$c(L8eCu^BmON&Ey?)_A0H^H~`= znTc+io9=~AIXN|ZYCOXJfsvUyi>vO5vC ziIY#vfvK`{ORgo;ot2Z8O-sn|;OS8#;$bAYJC%A6f1&;j#hE6#(sIK0++&C{Y$kdo z^j_VWX}NrsYZ6Z7O3b8Yb@9nL>50^WFiu(;?tdt~2mF_lh3iFf7hiOx^tx#hdc~!3 zCAkyRT$v~^Y}Sl)YUH9si5cmWiXKjpu2d#ZMrwLCec)v>yZEG3m@5;RBntTpcB$uT zhxaq>xFsMCv;|S1=;hjqke=2#_ zZkM=MEbc2&>)n~OrHsifYS*_L3Lf(9bH$2^C9SfG{^)TVU-Wwn;UgaWKP?IW1En(k zf4YuRB^G^*?UIy)TgWn@$D&7KhoFZs@nL0bmvH|dZuRLo6ULw=(yCh0ftB27aq4gu z65Ab}vxyHck)51{UNb#AxeHYE7n$fUL8*xfzx$Acr%3;W>LO{?Ni~wk$1Zmo(qC>M z$)>oZq_|0m*%=vWS#gP(+3{o2lH#)5Y02?Z3_5xsE-N#UZj;cBB^F;n(Wb=4Wt`vb zM|dY`|FT}MjK?c+buMbPJ6X#5y5cfRQgkc!a3%gN?AoYXqdi1vul9%XN;*hUfk<~K zxgECx%mPC}2SBsuFHGmo0{VFX8G_%P=uWy4C4P@Wz;o%2-_GbyRbkz5w6DR%y6%5? zYT;yfqWJBK?p^QmxYLKjZ^1RY!~Z^W547M(XtA_ir-yqG`s-WW!$)W@LfdpE+Ob%M zko(ZP3?(B-7o58Xev4xO@+5}K$wHoFtL_mGWGw0FpWhTcgh5QpRL zu*MTkKSX?@;{Czylx{GwyPv!0TChJT$DNsro5^wam@3@eT43;y?n6dzU%2>r-^JdmXC`#7;C|yN zS|_@j;@s(Utd|uxCUxpq*W~fE>q>E_d(v{UI;KpCOG_P->CVo~h?|f#DKW0QdrVFW zJyx6|WlASc(wM)eN!eZB#R36OSAd6mePnU%=TGb#}! zj@iHf5C`atUIZeqGQ(v|36K;|%9MCl(j-@UqPu7(#ho4R%1KJixU)McHOXDPOQ-AT z#W4Agv_P+3@q_Q9KZN!-l`ez--uFMG-{1cJhdBrI_}jJswEwPs?kjKh?|;8j=+-@a z|M5MB{qNta)E$=G|FFMl6)3s?zD_CY{O=zdFr=vd|6QMd$^HLb+keUZ|6S|<|9%T+ zclfWcfY3e`-w!HF5c_<`Sk4a|onkqUK9)-`#Bxp}wx*)AL31qUwPGJ>OOucNybd^q zy!3cT7s~~aKY;vxnjiV-@qi^3-#w3&oeRO#Nmxi8!Moxj@Y~|}6tb4sqEG++HR)%U ztI0i~Dde77U7A!q_#1w$Q?WSe^3@tGnz3Kd+ghA~NQ?jDz`O1&pSo(e4#6>5Z5kmfIZ*s?<5wdOTlT$Sj{ zR~_9IieZsgp1X3z)n#_%&sRgW6pFg!_iLReDDaZ^(4p(sqOra9exJLJ!g%`Puapct z(*#`ET1H#c}%7&J&BN|(XKIB#7vKeujhf7?2H@_*42{kMOTJwQ88&5=_%vzsasS$ zt`MKpgsh8B%*Z00VzBm$+!N!;m`pZByQg?arRaF9kj7F&+(~o{T?n0l#cO-$o#2jY z(rcNJG09CLP-+VCM<=IcWMq~Ur0;(7f@dW4q% zIg6G;lij4dn=T0|*}o9chu#&vYIhROLYJGn$@-`vX>PX%PpFi(TgC(rmSEpbMEp@h z@#s?1v1X5616F|&;#c5`y5(fj)zu{jzm6J~USwr@hNAl@evo8k6zW8|>b()Y-7Zhh za2@?T{5ia&l=LmRZ=92+Afz@uQnWakE=8v6lX3SyM-5NS%*F!q@R~eA>fK4zJN(#@ zW{iTCUu-cFg(p*d-5HrZ-L7n`hAw$Rt0Ke2INh1}cESYuf+t*$Q6J~ia)+iSjxVa% zbFbn*DvVelrLrEa7Y=QJ$Fuc9Q@k&vI^oGu}4rAqi z$!N6fmHfBwUHV|V#Xe;Mz7*!p%!0qOHdl5Mn)BhY1eUW~n-3e>v!kIopOuaN+eQ7Z zwRx^PtGV4)HP%80I1|R;%S0$3J5q{p}%9_w= zlCn9zz?Ghw?9R#_Uixe(isvoanK@b6ec=87WNGT=;e5!M9WrTD|yEuG6;tEKbpn?`m^=MsC`{@ZI6yMAVYzi5H{N@NQ9 z?Q^Ods>Rk04bp=fu&9j;{nthsMn$wz}G&eQzTDLY`o2AXwKCYdueO|j%`;K<2 zHlRJIJ*7Rby{sLgOVK^7dtCRN?j_x;x;45@y6w7;bYJQY>rUv-=q~E6>!S44^$ql` z^nzZex9Yp=`{@Vk@7E{jQ}pTj9R0)k>H0bPXZ4HpOZC$Y&l;8)UNgLD@EP7UY%%OG z{AeJ?#>RMKvT>Yoy76V>JI1ZX4~_ebhmGGFPaA(R-ZWM;)i>R1>SQvTdYWdK=9%6z zePY^cI%c|Js$lM5Hkj|VJZ5>$;!meVg#H@U?JR_*IysoT}WXY@t%B463fG4^+EUzo}x>Rn@iC?bTLw4|QMl zAoWP~SoIS1GWF}~_tZPoU#P!UA5ouH|E#{Hj@8uGwAA$14A$JQN!H|QW@#2^yqecE zTQz$%hcw^fIiA=2risv2)83DE? zrtV?vV;pE4X^bW;1D1H}qt@508?D=|yR3Vy2dv*)uUaE*)opccZEZ@M z$<`guc989UTY@ds=E1X_j%Vw&t-&+hZu`Xch3%N_yzPc9*51J08c(#h{XRU$arP|x zG(5kT>?`aa*gvxGwI8-0xBprt*rl=lO%~U<3TCCcj+M)VNby9T}t+tZ7sk*b; zt{$OIQBPDqqMo6CUcFSkTK$%Kqk0Q!$*1Z)>aWxn)FJg%^)=KKqKVQ})ST2_(Eg^4 z&{fgZ!82~B>#Q^Dp4BbUt#h9y_89eaPBy2RbImi%`Q{hRE6i`0-#70z-!NCSRI}8!@Rm*%jm2c?Z5e18YI(ro zwq#fyu{>#c+Oo{@mSrlR?b@A+SaPGcDMGn_P08%L#-pN zan=NDl69>0LtCW1hP`>X2B_=?wBI@QWoWO5?WgRQ=&um^E0J4x=21drffv@H^)|zk zyib{+oT!|poUWX$d|EkQ`GWFgWoK0{)gaaV;U|})TBP!!P47_kQIA*WYUXQR(7dc! zrCG0e7cKNt%~8z>&G(vfngUH_ZB1=`ZEI~utw!5L+gp2|Hcp$U9jBeFou+*P?R2sB z741sx8no1R(F1>^{Y<-8`;GRf_N4X)^u#}Ff6-RZRo2zOQ*Ej1sJo$?qd%a(qE{HI z8fqC@7}^>-83y9{O*Tw7JY#qTEp&rnJKE?MhNFfPhFD`=V{>C`qspi=b~W}i4mJ)q zCK!{9>3Fu&(DTkVzH0o+_>+;Cnwol;MwrH#a!pT~p2BlnZhGCc*7UwAOaJ=XSCgVkZ}WgUX2`k>WqO|@oNv#hz+N37GWGp!5JFPybrv|h2=Y&~ob z*wSrTwp`mz+vm3LY&GmWp1aCE(w>6eJJ-I{{)T-6TK!Hu`CIha2P%;jc=nZrdP2u= zTOTQ;2$O_|g;~Np;RRu-utL}%yoWmRxv*b2D%=v9D?2KODP78O$_!P_+C9Rb$ZhvsAgN zd8+wn`){e%soq6h`cU<;>T}gz)lpSYbw*XFic-g_o2y%^JE#S<)ZO7T2CB2w zdFt2HZ>l$=H`s-~;E?*5`Yif`U)49%v?u7KQE6^8Xwozu%~Z`a%~P7C z8lUE*=Axz+d`1gx8?9Qa*LKtP(hkxN)5fD#K8gDHx^|Ox5B$Yx?OE+r?KN$6U42~( zT^pT7m!M12P0`KLEz~W;h~RDAI<)WOrXNk0O@*c&=5%wG`B8H#i_&tRWuoO7%M#0n zmh+ag)}O35tOeFsTQyq)TN8NYPBw$hV(V$^Ya4BI!6QFvd&V~3_KIz}?Je5}=(j(& z9kl&uQ@{&b>|^OO3RWU%ct(lBe8HsbsT`~vt{kIGMnC&FtiM9(Q|?giQ3jMj*!-5# zr0S^}4EuUiPpiDDH&vVAbq}b1Qe9OMb(ETe@8#7kVNZ?PrtYfluXd_us^_a;QNOMJ zNWE8m5}x;Wb#+aBO-GGU(?=7hNr3Mi2m57fe$@V|ZH#{Pgzh`tCEXQWp)L|5pj!II z`eyp}`p)_h`q3EsjMq=rKct_jpQ~S>UyL4hmHvqSIQ;5Q@T<45MN4Zj*9jMa=yj2*)5w7=1bmO9FqWz03MGHx)QG+s1zMoU{~-WhH` zcFQ2k4EV^MmR*)TXfOLMhb+f13Yu$u5&p5Z&5V{X$~M84XM4gn*Y+$%JIihFW0Z5u zcEwg;t7mU)Z((m|ABuJnXHT#v!Om%R54Clu5~%`P#|bX@yF9dkSA@5OZNgq5h!KrK z8LMmp4>tuKZn1K?@-5|u;rbqgk2@Q#@mG}xRNtvW80SQ&E2~wguTJ%KShSL+s^%U| zLrpi$5RFSyh(7Tmta($b&_$zftB$^{K5AHdol>WT*Rtz+>H6sg>4xb>>*96Ex=h{6 zy4Q94G4}jk_p?p`t2c!=>kNNpg-0WXDzN2j!vaH7V>_ePxZU`f@t`pSJ=qhchUQl0 z`^@q1G$+h+EiYKsTee%ySgu&wTlLmtTPDVUt8G=nqq)Tx34CrpWItvP+E3fhQd{6( zX4nN=JSQv`yuxPTOW`~$P+zH3_EOGJdQtOME8j%z+o+tNI-&Yr6|JtPZlP|cR$^?| zM?FLxr=F{RS-l)JYnytf`g8RGw9)J8LUoL$o~9|r<0ega%^=MvO_FA!W{Tzsw9Z#B zLf@d-rui5ny#1OZ7~!4M{ERVPfu^FirM9!SpLPUBcoVf#Fv6RsU8MDDU($ov6)BI;+Fej>d8Ll~XU)IW{!`9l3m zdar(^{!RV67zGCO$Miqw&+DTM6=7AM;X~BSy@qcLhYiOK-x&DF5#w<@mmJe< z(-#=Y|6m$x4w+r(E0$O`q9*@jiLus2KR*&ad!qF@>k{j$)-~1*)_1L2F{=Lpy-1X; zlC2iT_Wf;1wrtxY=r2CDePbi`Sd7{0!@~>qZuSxO@%G0sCf{QJ7*F#8eU4mgxK0zH zuAmF|@x3sj8zjUD2|}_kPRJ2*g-3tzYV3V*FZ(DA3c`)amLec>3?D zFRFi2x7TR#ynACj??ewALK~>2ZKV~oqqPgPZ^7?>rrobSr>&%O==$pJ)7`I|gFbe> z?wIZ>;;fqbCWx}Mdbd79{~E?@@4^39HZ;U2y|ck>$iN7F8b;`!8on|dF`PCuM;~G_ zI*i?oy^UT|WAjn-!C_`mK9Yb?N8$(A!7ehb9D8mio z3|Zk`V7}q3(PZjnT4eg!6lH$fTxjMjjVvmRHTqdzv1~y5--FS`PZqni2SyK1S)a8o zww{2Gs$i>Wd&u^jZINvi>eUw8m$t*UbGCTI3N!2r5Gic6e_=mr|B;RwgjoFMDj`)6 zA#@PBpdRH2yOrN6HR$aot7oZSQv1}OseeMB*HqIPUibmc^B5O?gf@MzevQ6?;U$d9 z<{EDpV@-8U3r$N*J52{n-=2$LS3N6*b<6AYZ zd8joW(a;yxW7Z$6oo$cXW}HtO+F`DX#MjL1h8i%H@W`yQ(^i}6H)wM>9X9sChv>DnB+GARWu7_?2MhWSc-)Y0 zSZ-Kn_yj%AEkhfl!PpDF@G;|?7^@yc406R7W2$N5O=?pY({Pg;{rp_maTP|ZpP2Te zU-`upYp!p$m`7tg@|5`nL>KSCZyq#%j|ihuIJW3#dC-!Dh+;YB55BS-M14@8?`dc4 z3HwgQi1K|{IB5OFTG7_ZrnZelf0JRGYJ1wY7`5Yl%oluXy8ypY4_>rW*xsY<>9F{- zb}zihDQa(Lk?)8RY6^|VWaRqdX)p{Pkup9QdikhX+-ZaR++AR zR5=Gx#_P&=mAm0rFXE{*MWjf_in*$%5O2JudQbJK>X_=hic{BBw}F4{ffAq1z>tojEt?ST64qGo+uVFM)*Vf!7*t%h!Ala6KvF0+{ zTHAZJJ+?!(Gq&rt3id|!_Vyka2_@Mx?2p^$*_YVgMr+?^KWV>dCke6S0@_VAp#f$C z3}`)r1-Foe=->rmHJ;>F;WIqRlfqSjD61)(VHTjfa)>fX=~3n?pFr=rM(J06jYyzC zSzXmo)lwy>EQldTsghOMi2E0)-oO*xjq<JX1Pms-td($iFK_O>T_xpHM%mei0-6 z_3Eu?g~!xCVkA{r!=qPmz>f^WNNNH`4s#KCuGDPSe1e$sM@)7fXQ^bQtMERo-1x~ZRWL=Fh!Y9^!Xs=hS z3OwyrnDHBC8;kKlemJ5yWIK(Sy$E|XJn7DMt9>x$fTm#%V1a$LeWQJc{Tust_G`4w zdeCOEsUWmOi!}=ag;By-;UQr*dd#;lTx2ivSU>YOFsS;F4s`p)YCLVJ#49It68I6uid8oT>CBNDIzetsL^%N4b`RUrt0SFyt;RFdvxDo zt~f?tU*8EM(P8>A@ayyROEB-a74waUFy0Kpr=LYV3+b<-uHAw!prg;h7)iP@OEJUv z97d3|=lIfi)OZQAPqgPZU{-h}W}I?Ob1+x267x+Tq38b|kti`&GdIE9qSf3NwJQ-Z z=?wVQH_bltM)PL#7PB9oV3&E1Ie@wrw4AntEJMS+#v$|-v9^|&G2UtGZeM5**?+Sa z*hzjYvEW5%v`|H;g+8E}&{pUi9z}K+`h{l&6EI&eF+5+8AD%C0qim1<+^Xz{8Keg= zPmrO^!VJ=v%By((kE>2$e(wTe(QDyoveBD;q!2xejR=Kv)UEfH}E9h*M6w|09~cVXOr5M!&G`bdnd zY8aZLH&+{shF0hEEn_2NTcaA0 zfZf>5*xxw9I2tp*>BdRMM~qKkth3noit#N(v7e&%KLP(8GF~$lglG8Mz!PXq4m{04 zn0-nxy(^N03wqV}phN?dLf4#aJ=6PrY=~ic{r@;>_#0@bB*)RlkYVCY}A@k%-Lu~Pn(}Jzl6Cw z>XW}lTB%Cgq772f$2Mz58v^{ky?>E4)^ z9c>+h*lsGUOUK75U{@p|)TXdI|l7VVJQ<5j^OxX9#nJmtf^}cU6@UZ{K+FJ%>efDwRr-6WgV1j|* zX2&?Y1Ly1j6C3Ov>a1Cqv&C+Q-Old9?(PI@&c<$iKEDIpb=~)Uy?kEnrQ?4d$1lEh zfbRCt4+e*OuJ<>D8f=CthMH8vriK=Vj)q=_1ghc!aQL%^%Z60Ledhd+hAiMkE;jk@ z%vvM3p;N)xR9bWi0&5BJF;rt}~#qkKtdsf<_J0ji3WB z)%~U0LsyGri)pCuM9&-y1~{EAxm>@IjpnGnC75ZN!bn5;y=oa7fbRWfY{4Yl!_?n2 z0v2>3IQ$0s*&%juZ&(zQ*-k&JY_4UFF*h@};oA=|4`(Kx$(LUO?y}Lm9ai+T`3hhD zDVU(3FZnGcEamv_7E2_^OHICeV=8V3OIL-ujI~T+r=3sTUBm9PgZn8{Rtl)gQ@FQx z^uNs39L&={T1#7X%+yt_b*#6Au0Q}nvTORn)!uDczo!zMzm}tIOZy1q%it%j>(R>j^*^jpAeyM&9c>O+3)G7T%_Obim%kSvuzJ^?e zg6w62(^pa0ay|NbQ$rlRy}hCHfA#la-~?k0MZialW+%P51=z?CkoDE<%X`fy&1adK zZgZkum_LCt`&t6PIxBFC>w+>1iuW5c`e4g&OCmLXr{#pg?NZeYCG%5uPEd%o5a^KH z+M(RoKk3`s;Ds)L5IwLyqvB__h1!dP#q|e^yJRotFo2QnWjn47yLQNVj;<-wkw45@ zAy>GoG~Lq5lzj}Y<(lgrd`l20b2#(TPi{T^alU&U2*f#l%fH!+EuOuevz~`Asvo2e zre;^-vuvOxF;wFh{4Tk`&WeMW_0|RG2k2kv^U(Dw88#R$7@mVQbb;Nj$$ebFG*b>8 z!VnY)0VoXyfT=&V_*$F6R-OcnbipyNww>lL@xWTWus2}3EA5=ZMi>QZc+54^t&@L0 zjTw$Jv-bb$x~G}bKkB~e$}w>_g>5Me2G-QjkBw^^RpO1IAQNsm(7L8zusNyQp{AeN zs_K{;nYx<#ng)ZvE`TdZrt_XPJ!8A_F$b9QusxSkHA7Im7;|$fc4v023Fay6TL#dN zdTh@fE#1*a3;}_iKrNU@Es#pQi#hB9^YC5Rg8bHScs(<}*eSNG8`j5k=?_*f7=qmN z>5{PPO>OPLR~J)5cQIFGvX=r0>1hAce%b!a9*9Ch>-^c-*4cw;XtHxA(@-*uX+_4#0}WP6>*Z@S%Zh?(Ud*r`lLe`6?HLj>4& zb@tcx#zElT!%WLe-%MWSU%>f)r@Bs5X#Xa457H6;FXkYsYB+V(#x1CU&ZIMEVF+Ju zp3*PurH5Uhiay{5e6)PC1Xy$N{fePruv_baDK)jmSzB`#I$OJfm3qLchp|zdu+@gO z{@p$VJbD_lIj~vU-BpKFfm6)$sJAwoUd-_bl`* zg^S!mbvw+q!8r}`(-h*IYP4CkLCiJbY7aGn9aRE7iq_U+j%>~(*`7W)NxK9Tskpu> z+JQCt&Qy~dhL?s4#@WU<#tNLrSEgK4mNw=;&6~{|Iaf(=O>5ZMcPeK1997`9^&xfO zy)~=NmopWD8fUBRE_3-8TNXM>J$i<>qo$)5)qgmw$yqoPKc?n#)cab@aBW@PUAT|R@H`MZtoNU-{*?#`U6k?yH%9qT!?Zs?B^n+8SYM|Dx*O@jR1xFWgTvmT!|oTUc9$-MogjrFJ;8 z^fK*QZL;=+_J-DnN?%-8R;NdY;i0nBWwPt38vs+Y1de92Zny5B?j$!pm0JIq8KJ@d z*sIql-u@r-QD4}p0^se1Ye_Iw;vV-f58@urF|R^Pag2WN1!7$cOg@%+98Wz?fKicZ zyquY62UB%s)G$u?_U5*Bwgk|x=}bJrN{Rsbcqq5GoZV)3fn|2H z51@z7MMEKqr(0+zG!9=!5wH>){ky88KI(}!jt=a#y&Z!c!yPLXO16g{ej21d#o_JD z?F?ft^1#A2b#~_Wo9x_7MZfC2?R??<;tT-gjBr(RMY&@51*f=@n8H`O*1EQ$o4V|J z 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

9$^wO^x_?CN%pk)_n&b5Td6o6)KM_P2jA z-|3p)-9Aov^L28SICbW7yfK~TY9*5r7vrFo<~zMCag-|FCHPeBIO)#t3H+7zMW19+ zWsHv351H?dlc`-!U1Tr4t*_x^{SdQWKcRP+!##Cox`6s)6*uHn+(-xbM(6Q1dIrj= z-*5w3iuY`IKi_Dt-<&!{e`xvd`3N`95-f8Xb;x>H=2l#M4>N=Fb9#JFQ!ieHlBF!D z2;5BiTl}8v50RM$e!F%Pw8PUdUV=JI|%Ryn}42 zmF}o>@Ol32`bsL039kU#6$-Iug1?zRj={B>{pQ2TC;<45#T9EqCf z+zfG}K4YEh!fI+P#V7+mj56>jUA_~+8JxkhnWEo@Lg7Y~V0U`AFtU=<2)*MOQ@D?7qRrP$aG8D_rNDsT?=B$;}ab_1^&rJO_xC;L{{tM6H=y%5YRk$x)fQOUwt@$7t z*^hIs`>8&h!F=dVWQ)6)s_#N$^f!J})vr>gl)V@o(R(1T4({rskk_;HX`Ld^sgPZN z*7;h05r3y#s%mcb`|Y^X-Rw8t9N}Gh+WT6sB!hH2Z*N1L@Dn1Xo%u`@MU!=zrXH%TuYoHQ;aE<$V*6@*-z3H{xb%U%@ViR?gCQg2$P*KMrr45f;#I zDD?`U%b|_$(65=Hu6PXgzmhNht@w*L=6?)dPUqh0b}}!kDxHq+;{a!pNoH; z+Wtf6xXvWnYw+q^@3#zmp3R|$)}Mzb?yI4jtLW2yfr*Y$zPcZ!{t?3cX{wwo^HKH+ zEl{&q!93)dgGp=bY8 zY6tT%chR5!Tl9O*-|E}w;-^s{xj)^7+Z1dY<-LBXvZjfK#|FoMvVh{b?2bhIBNNvw;lKL6?vE#m46>D7+8|Hkx+??m# zXDX?0UX34$#ouTv^zsfSt8c}pryJLkeW;nnvvoh+AKJCAv{v$vM&?_aP{XcMov%XZ$2>gz7Q ztNRPo+aF?X;~%`c)=?A{F}}>R=yY8`eVR}a2MQQYC`X}_-pF+oS8kMmJPSz5?@9+C1?n~#oyoxEDh?}#T3P%HUb_<)+ zKIC&N*O$k|3vKoqKa;eF?{+`h{fFsbJkGneWS^rNeYT%}xPG_X zb1kpq2KL!j@e97i^Y?q`D|hl*y3Xn6;MyP2H(j8XyR0^H)m)dwzJ{FSjnv2#paE-6OW^sZC%euK{KC4L6SZO2@Xm(oY$e~re?ZD@VS`@lU;ZGVBC zSD#{^;TO@mPM{5bG~pDkyU7rbFhgHKR`PN7L_O$tdZ&}Gr3Ul{UXlCp5m}xhIP5!V zTX3d-J5Jy4Ve0i!`b3w|t-Kp=B+EwD*Ks0uLivYLD>`4KXZ?$D79JNDkgHEp>3^Im z?D4W{2x%{jv|_`Vu+bODS`P6ZALZ_H?(>_8(oJ}G-RbXxFS>Iyvc~%^So1n)(7nai znRnp-cng)rC%hNSKl37IqceiRd(ReKv=HY4;$R^p?(1NXd1 zx@xat()o3Kx1)TmStxZYn1or*Yu${>+4v4O`^@${wr;$IIDHab(G&FG*D{H??)Mq( z#2W7tc_#Pz`(PAD%8rFL;Rg3+&nE7@yoC9Mn_%PL6aNi(nLR?rdM3*AD`4Tf@hp7= zZJxXHcJnv?n9tEKVWRRTUcxVw4sk}7>Dax0U**-yWAEkF$+srI#rE01PlkS;>r?AK z%e3lQymYTX$?B#9oL_kif3nM%xO8vaQ99R`z?C;a5?^5A=O{WE%cRHa;N@9*7|-I! zaRq-{=dt{LPQ@&B!Dly|#+j)1FWURb<7byCkQv-H-W&Kdn4z9N#;vGO9Z&xfZMfUx z@;=T&KO3>X%zfkBjmp?Dd#T_2^bO|ypTw2SdAhxYN$}fvAD-YvcrGkpch|*a!X0$; z+%)ia;^*-eY(y#kR=WS+ppyCoH~&kicom{)>cA2206g{`h%D}Rv%e8l_>fn5{*Z22 z-0#eLBj3@G-^~6)rYGY}-CT}l>tE*;X+Krb=zS%Z$ofyC?y(ID>tL?;<3#NQvxp_Q z0xRPUx*|3&&{XL3(pLZ#46uQn0AY2H=7sf9Iu*HaF}wc1w- zTiKU&7rXV2_`UbPCMP+aUTrO&)qf6qy&GM}7(Fz1ga6c5@ykzYboWw^8blTPAiB1d zbcS9HeWj`Tyx!NRM|f|)$E<_v5gGJ{Y3}Jg)LwhpAnJDUtw>~}zkNC6d%mwJw)$80 z9=fM<+|9q{>pO+))45syIXbv^ktu(NX@r0Bn^>RrRmM8z*4(x}*L9oV_WDP9Z(wTgfr{ z0kPESetYY7G}(7jvpvS9l5?0^*^M&lbM#J}<9-_U*~{j~htU8yRqizq*+Fu>C&-NQ zcpcw^M*)>Q{#W2<$lP9nT%7hVVngye-}~R+0ly?zq!t5n0kOO5vuGUy7X2>0UE z|795Xq4gK>Zfs^o=%Yt0;jYDPHFp4Sh||ud4Aj0o9H2Y zjk%xE^pEHl|CBENWu7oyzVRMzjt^5OKZ?Tf1i9lMZ(PY_$+=XJ{)Fks_ZC>uu9&p$!6a}dArZ=u2c9#z33;YM`OHSufcXN~wxC;t$y zK)v@SI;1zUJNH(clLo1{6!I&S;6_!3a^SU``fI3--bAhVHhza^V9G31T|4O5ypPSC zN0`q(N+tL7?b**(l}IghGgCb+)I?ehbAg;y}ObpyJ_o0;HynqMNj>?OFnJN|bsl-q9ow^09! z@pOI#6{iF{(8}2;aHan}oUgB?o>qwh=4xE3zKloy3RKYfzPIygHti;vvbutr>~<8K z%_v2F&V7VJy|5rw$Zzmwsy)k!!NW{|xVr4G`3+7-S@sUL7T<;@-T4Uh+Rx$AS%|83 zyLT|Zm5kff-$^#l8acS`-hD$B)uiyvozz zyFK5#TgNHTpIUbcv&U&ps@q`lUb5r6{j~82-L4-JAvbG$77DairP3!Sa;_$aTi!ac z%TI0WVfVyed%eTwdG&_rB7W0*`~1D1J)TK@5!U_&yJMVR;iI^5{)B3g+iT{$O>Uqo zc01J-S1lT%*E34)95V&6Y~~!te>Y<_17XaerCor_me{%!Tlc@?U-WxTd=p#aTR0)D z>)N;xf9pci^KYD5M#yBxp67NlgUWJ_6ScsZT4JkXY<(8f{yFSx&ZC!6z!@t-&sIXt z8>a_WhPQYH)w8Pg)l|7_(TLRfDZ)m)Oq=QV?BYDOp~~-|4$(z#v1ffRnQ}iJph0SF z!`u}kOnQ$I{|V@6iiz(TsB?}k`vNt{C3GgSR2Gw{|9Ymq_<61}<;;Y;$>eG>?pof~ zI&K{|o!rDpZ=u%lpLb`Pq{lhUT{VjiZ=Q*(MOgO)8xXSiQgWER%H!sGp<|D8fT<{} zq{CND)w>pNn>wnb4Rn*6AfXnt@2z}W?NnAenTGD>jqjy`+Rs$GvHGL&@lfR^6`rpv#T}++*C(*^plJx<~ZdW(0S$`G3 z`rDYvey5)){s_P6xA~e%m}UDWH~(5X0Uze?dxSjIIe9*jJ{JyrFC;Uwp^B;Yzu~@) zRTso6`1|MLGuA=x+)Z77+kB5b$I-wYl7JMZIHpfgzFZ{l2!bMbBIOBACvjMK?{GqVsk`YO=JnfY5lj}i0!=x;@> z;_lx&>8L$GrSc&(`9FX<+}_VW<}R*CUWyj^-DCqF+^b)omcyO^IdqfIcI`<{EX|D*sL*%FTi8u?LS4YeHt6(`rLb0SK$4%-L8_C z!63y{gW}{;SK_Wcjna9VT3XC|vaRJsbF(AoFsZx&J>gC0{O{uo{P*~q=xH^2MaBov z8Qh;Jqf`Ec(l??t{~#`5pN7RA_L_6IYq$i5$`t+~Z^D=7olG?CP8QK2+JK(^Y808b z5tF-cz8Yg%O!Gc&B|H#3cv!4IfY*{|t z_wMuz8A&18R~`9CFWJ`&*+?N?y>;+IFOg(og50zq*33T&al@%23+YAEGsCM@Xp11{ zdR{8$IW}vH=&|+kMit`Q)JsLOkRD+#6DEaJmwK7gErf7;nIJ5rR#b=HXDZ4^UC@mR zYKs0(K3cn4dTBj46VI-TEu0gZKP?tZlF^jY8>mF@P)!G<79M$_w^=LGbM5r^JLz0@ z^BwduztQh!m4{GB90*33sO)>7sEtt(X%J*AfCd2Dr(d3U3+>*W>hN8>X{H)c3IK;Lu}9sD?c z(35n~-Hhg}pVD0LbDAgoq-M6C)y(tLnuUH|v&2tqCei7Y!&Q~^MyjE!+ULz~Hqn1= zph1mXlpOAcJUaOWbk~c}$KK{EQ`-#Lwp zL;RDdf~GlvvrK=@bKkjH?-Sg4Sy48X%v^fc`OK6Q;%!$<@4=AoCZjT{n-%1}RqX7l z;pA@ncN}WkxGOuTnRIcgd#IcB;V?At0++aPGPg<2{4|r1v+SLiXU1s})yN5IYFSiS zmOXCr(bpBSr?Z$F#gJPk>2#F;C#EOc(dTsHh~d7bUNi>%=)eZa$cJ&u9HGZLM$LZW z9e!&L!9u=dyF?fC^nba@eP(iL$MfO|c{RG`x)qv)yi4J=U zRiIY7E$z5obfSpqcGJPUWBpWy2FWajsq2qG2xBLG6sPEjx;JhPzq18;NlWCtTa32VP;*W`&ttNhiNjhZ-RpS! z8_;n!{X32Y-L}VbK|f4BNcVWyd*h8#UmK^wHi`0c+B3u4zwzPBp%RpL(g(7LPIC$U zfH;cUGI4-7KpgPDa8VEkbf~)WA68ey0TZZZ{~$RaR~)ePJ3nr5KrYq0eCEjuRS!@- zK=lB1S312R@8SS=0^2Z#g20pb90fH)vyIiOA)APx`* zhy%m{;s9|##&STDI6xdA4iE>31H=L1fQ;pUR&jthKpY?r5C@0@!~q%00iEIiaez2L z93T!52Z#eQmIHdl0pb90fH*)LAPx`*WGn{^iUY&};s9}gI6xdA4#-#z7!e1E1H=L1 z0C9jgKpc><955jc5C@0@!~x;}aez1=V>w_(93T!52Z#g20pb90K*n;wf;d1NAPx`* zhy%m{;((0hfY^Dl?Ce-9X0lAS$uYSm&*Yl|Q)r4zu_-ae#7)wanQ~KMDovHCHZ`W! zY%_JH-ZYp-(`1@Wi`ivbO`B;q9j4QCnQqf#dQG3{Hv?wS44Gkbz>JttGiJukgqbu` zX4=e{SuCZH=w9 z+iab!w+*(@HrZy|Vt3hA+h*HshwZdow%hjDUfXB;?SLJ$Lw496up@TVj@fZLVJGdB zowhS}*3Q{^yI>csI6xdA4iE>31H=It%K^FK0C9jgKpY?r5C@0@GL{1h#R1{~aez2L z93T!52V^V<7;%6&KpY?r5C@0@!~q%00p;QVaez2L93T!52Z#eQmIJEA0pb90fH*)L zAPx`*WGn~Ni37v|;s9}gI6xdA4#-#zXc7mA1H=L10C9jgKpc><9MCEb5C@0@!~x;} zaez1=V>zHx93T!52Z#g20pb90K*n-FuQ)&)APx`*hy%m{;((0hfI)G9I6xdA4iE>3 z1H=It%K;|>IGjA5mqFFL0Ow4B4Y@1_qZJy1y1-8%@*t=(qpY`tx;jkd`)+ZMaaw%Rt^ZaZwJ?Xumr$M)Jj+iwT#pdGTq z_JAF+qjt=W+X*{qr|h(yv9os0&f5jMXvG2I0C9jgKpY?r$XE`@6$gj|!~x;}aez2L z9FVabP$&)%2Z#g20pb90fH)vyIlzbm!~x;}aez2L93T$JSPm!`2Z#g20pb90fH*)L zkg*(4Ee;R|hy%m{;s9}gI3Qy=piUeh4iE>31H=L10C7OZazK+fKpY?r5C@0@!~x=f zjOBn31H=L1fQ;pU*xFcjb}SY%Sti@$m|T-* z@=bv$G)1P^lo(^;CTYq{xv4Ofrpi>C8dGbwnL1N%8cd^UGR>yN>@uyU&9s{i(`mX) zx9KsxrqA@70W)ZZ%&<9NM$D)gGvj8$OqwY(ZD!1@nKScd!7Q33bHc=Imd&;~HrM9a zd|O}(ZILauCDz!uP1-VBZYyl1t+Lg&#@531H=It%K?Sr0C9jgKpY?r5C@0@GL{33I6xdA4iE>31H=L1fQ;pU za&dq-KpY?r5C@0@!~q%00oCFFaez2L93T!52Z#eQmILa<0pb90fH*)LAPx`*WGn|X zi37v|;s9}gI6xdA4#-#zXcY&D1H=L10C9jgKpc><9MCBa5C@0@!~x;}aez1=V>zH# z93T!52Z#g20pb90K*n;wpg2GrAPx`*hy%m{;((0hfDv(kI6xdA4iE>31H=It%K;PO z0C9jgKpY?r5C@0@GL{2o!~x;}aez2L93T!52V^VWDg{ zuBbceiF%{Hs6QHr2BV>9I64rGM5EDIG#*VvlhIT(9nD0u(OfhiEkujaQgkAUC3S!6 z{?`4SvG;eZNPFY$3Hu-2-^rjXC=V)v%AhK!4r+qhU|UcZ)CUbgW6%^d2Q9&_pfzX< z+JlauGw2GsgPx!_=nMLTfnYEg3WkFN!ALL~j0NMtL@*gl1=GPyFdNJT^T9%}7%T-R zf>@XpW`{XpZkQM5hXr9_SQHkAC7}u9VKOWW%fpJWGOP-#!5l)6v;dD3?&W3a0 ze7F!UhD)LHIOTET0C9jgAY(ZoR~(>vt~fv(APx`*hyyZ~0}90f;s9}gI6xdA4iE=q zEC(2IfH*)LAPx`*hy%m{8Os6X;s9}gI6xdA4iE>312UEas>K1~0C9jgKpY?r5C>!| z2h@oJ!~x;}aez2L93T$JSPp0s2Z#g20pb90fH*)Lkg*)lDh?0_hy%m{;s9}gI3Qy= zpi>+m4iE>31H=L10C7OZazL**KpY?r5C@0@!~x=fjOBnqaez2L93T!52Z#g20U65y zBjNyYfH*)LAPx`*hyyZ~117`);s9}gI6xdA4iE=qEC}{xFq3A=Oq&@qYv#qCfjUV>@M4C+ibh-u${KccH17?Yx``!9k7FT$PU{BcEpa_ zF*|N2?4+Ht({{$r+BrLK7wn=H2Z#g20pb90fH)vyIUrXYAPx`*hy%m{;s9|##&STR zI6xdA4iE>31H=L1fQ;n;BMuM;hy%m{;s9}gI3Qy=pj;dv4iE>31H=L10C7OZazM2> zKpY?r5C@0@!~x=fjOBnjaez2L93T!52Z#g20U65yP2vD?fH*)LAPx`*hyyZ~16sua z;s9}gI6xdA4iE=qEC+Oo1H=L10C9jgKpY?r$XE{O6$gj|!~x;}aez2L9FVabFenZX z2Z#g20pb90fH)vyIbcK_APx`*hy%m{;s9|##&W=fI6xdA4iE>31H=L1fQ;pU8F7F( zKpY?r5C@0@!~q%00Sn>)aez2L93T!52Z#eQmIGq1jAduXVlk6tvQ3W3HF+lA6qrI& zWQt9RF(z)3rp%O^3R7vSOtq;owPu^CGxesyG@2&UY+B4N(`wpGyXi2Urpt7j9@A_3 zOurd0gJ#GKn*(OVjG8esZYIp6nKIL6#>|>IGjA5mqFFL0Ow4B4Y@1_qZJy1y1-8%@ z*t=(qpY`tx;jkd`)+ZMaaw%Rt^ZaZwJ?Xumr$M)Jj z+iwT#pdGTq_JAF+qjt=W+X*{qr|h(yv9os0&f5jMXvG2I0C9jgKpY?r$XE`@6$gj| z!~x;}aez2L9FVabP$&)%2Z#g20pb90fH)vyIlzbm!~x;}aez2L93T$JSPm!`2Z#g2 z0pb90fH*)Lkg*(4Ee;R|hy%m{;s9}gI3Qy=piUeh4iE>31H=L10C7OZazK+fKpY?r z5C@0@!~x=fjOBn31H=L1fQ;pU*oCp|>{u*j zvP`zgF}Wts|_6=7fpa zESqg}Y_83-`L@6o+9F$QORTYRo3v%N+*a61TV<O8zC+(D-wlj9t&e?gpU>B`8KpY?r z5C@0@!~q%00lDG;aez2L93T!52Z#eQmIDgK0pb90fH*)LAPx`*WGn|5aez2L93T!5 z2Z#g20U65y<>CNwfH*)LAPx`*hyyZ~1FFRV;s9}gI6xdA4iE=qEC31H=L1fQ;pUL2-aMKpY?r5C@0@!~q%00VCo7aez2L93T!5 z2Z#eQmIEfl0pb90fH*)LAPx`*WGn~Fhy%m{;s9}gI6xdA4#-#zShz6Oe2VrC$AYXN zJID!ggS;R=CHDPVIEvyUc!-lXi zYzmvhmT*_t8n%V)VMo{*c7@$xPuLswh5g|`I2aCv!{LE&BpeOL!trn-oD8SJ>2M~T z4d=r7a3Nd_mqKyCedaWIysY^P0l6flMBhk8o61Y&rwUSqsiIVIsw8Dn@l-NZmMTwGq$*QYsp?cssy4MP zRhOzyHKZC-O{wNoOKMlDHPx1CPj#d^Q(dXP9**---xNw>C&0f+0wbv`O<~b#nPqH6Q!{zE6R>? zqTDDi%8v@7!l)=Jj!GgE#iL|Y7L`X8QDsyWRYx^ZZL}?_i|V6>s4;4anxmFzSJWD{ zMeR{X)ERX}-BC}}8}&u~(Lgj94MoGzfoLQejmDz!Xd;@7rlRR+CYp`rqWNecT8x&W z6HzRwTv55AI3Qy=pc)=sp#WD0*Io`uq36zYghwbYZ$EU7RjSn{+&# zOqZq0(-rB;bXB@KU6Za&Z%fyu>(dSC#&lDCSXlx;x#I?oIcl z`_lvI!SqmiIDH^Jk{(TurN`3~>B;m|I@WYitd&1Qj?J}sHs2Q5LR(~uZHYBDZj-jm zmfH$jX{&6tt+BOso2|3;w!t>qCfjUV>@M4C+ibh-u${KccH17?Yx``!9k7FT$PU{B zcEpa_F*|M@YdF5B^*qt;nSuXs>qW6j{_%hMH{)NS|0x2BfFhs>C<2OrBA^H;0*Zhl zpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H; z0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2Or zBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs> zC<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%I zfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`e zihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhl zpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H; z0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2Or zBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs> vC<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*b&NPz3%5(Eh4@ literal 0 HcmV?d00001

oG;yxo=eh*?GXQw++o%z{=a&*MqUc;UfnI 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%0A!3Zu31aLNaMJ7Sy#B^qlE&04k?$k!&$`^VLo$)L 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