From 2c2f760f4439078c44edc6daeff8573963e92bca Mon Sep 17 00:00:00 2001 From: ekeeke31 Date: Fri, 28 May 2010 12:08:00 +0000 Subject: [PATCH] .optimized memory footprint .improved hardware initialization (fixes Ultimate Mortal Kombat Trilogy) .improved soft-reset emulation .fixed some menu bugs on Gamecube --- HISTORY.txt | 9 +- source/cart_hw/cart_hw.c | 269 +++++++--------------- source/cart_hw/cart_hw.h | 12 +- source/cart_hw/datel.c | 53 ++--- source/cart_hw/eeprom.c | 6 +- source/cart_hw/ggenie.c | 6 +- source/cart_hw/sram.c | 31 ++- source/cart_hw/sram.h | 2 +- source/gen_input.c | 166 ++++++++++++-- source/gen_input.h | 1 + source/gen_io.c | 75 +++--- source/genesis.c | 11 +- source/gx/config.c | 2 +- source/gx/fileio/file_dvd.c | 11 +- source/gx/fileio/file_fat.c | 12 +- source/gx/fileio/file_slot.c | 427 +++++++++++++++++++---------------- source/gx/fileio/unzip.c | 8 +- source/gx/gui/filesel.c | 9 +- source/gx/gui/filesel.h | 2 +- source/gx/gui/font.c | 21 +- source/gx/gui/font.h | 2 +- source/gx/gui/gui.c | 128 ++++------- source/gx/gui/gui.h | 1 - source/gx/gui/menu.c | 54 ++--- source/gx/gx_input.c | 18 +- source/gx/gx_video.c | 72 +++--- source/gx/main.c | 99 ++++---- source/loadrom.c | 122 ++++++---- source/loadrom.h | 49 ++-- source/m68k/m68kcpu.c | 8 +- source/m68k/m68kops.c | 196 +++++++++++++++- source/m68k/m68kops.h | 5 + source/mem68k.h | 2 - source/render.c | 8 +- source/state.c | 20 +- source/state.h | 1 - source/system.c | 23 +- source/unused/win/main.c | 2 +- 38 files changed, 1089 insertions(+), 854 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 8bc4943..51f4977 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -60,12 +60,13 @@ of samples per frame and keeping PSG & FM chips in sync. [Gamecube/Wii] --------------- -* implemented new FONT engine (using internal IPL font & GX hardware rendering). -* implemented custom GUI engine (with PCM/OGG sound support, multithreading & using GX hardware for rendering) -* new interface design (incl. IR pointing, game snapshots, visual & sound effects, BGM...). -* improved audio/video back-end synchronization to ensure 100% smooth video & audio playback. +* implemented custom FONT engine (uses internal IPL font & GX hardware rendering). +* implemented custom GUI engine (uses GX hardware rendering & multithreading) +* implemented advanced interface (IR pointing, game snapshots, visual & sound effects, BGM...). +* improved audio/video synchronization to ensure 100% smooth video AND audio playback. * improved reset button behavior, now works more like the real Genesis reset button. * improved lightgun cursors layout. +* added automatic ROM loading feature * fixed stability issues and memory leaks. [Wii only] diff --git a/source/cart_hw/cart_hw.c b/source/cart_hw/cart_hw.c index 9d7babd..792f6a2 100644 --- a/source/cart_hw/cart_hw.c +++ b/source/cart_hw/cart_hw.c @@ -62,62 +62,59 @@ static void special_regs_w(uint32 address, uint32 data); static const T_CART_ENTRY rom_database[CART_CNT] = { /* Funny World & Balloon Boy */ - {0x0000,0x06ab,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}}, + {0x0000,0x06ab,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,1,NULL,NULL,NULL,realtec_mapper_w}}, /* Whac-a-Critter */ - {0xffff,0xf863,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}}, + {0xffff,0xf863,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,1,NULL,NULL,NULL,realtec_mapper_w}}, /* Earth Defense */ - {0xffff,0x44fb,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,0,1,NULL,NULL,NULL,realtec_mapper_w}}, + {0xffff,0x44fb,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},1,1,NULL,NULL,NULL,realtec_mapper_w}}, /* RADICA (Volume 1) (not byteswapped) */ - {0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}}, + {0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,radica_mapper_r,NULL,NULL,NULL}}, /* RADICA (Volume 2) */ - {0x4f10,0x0836,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}}, + {0x4f10,0x0836,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,radica_mapper_r,NULL,NULL,NULL}}, /* RADICA (Volume 1) */ - {0xf424,0x9f82,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,radica_mapper_r,NULL,NULL,NULL}}, + {0xf424,0x9f82,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,radica_mapper_r,NULL,NULL,NULL}}, /* Lion King 3 */ - {0x0000,0x507c,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}}, + {0x0000,0x507c,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,1,NULL,NULL,default_regs_r,special_regs_w}}, /* Super King Kong 99 */ - {0x0000,0x7d6e,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}}, + {0x0000,0x7d6e,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf0000e,0xf0000e,0xf0000e,0x000000},{0x600000,0x600002,0x600004,0x000000},0,1,NULL,NULL,default_regs_r,special_regs_w}}, /* Pokemon Stadium */ - {0x0000,0x843c,0x70,0x7f,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,1,NULL,NULL,default_regs_r,special_regs_w}}, + {0x0000,0x843c,0x70,0x7f,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,1,NULL,NULL,default_regs_r,special_regs_w}}, /* Lion King 2 */ - {0xffff,0x1d9b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,default_regs_w}}, + {0xffff,0x1d9b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{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,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,default_regs_w}}, + {0x0000,0x8ec8,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0x000000,0x000000},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, /* Supper Bubble Bobble */ - {0x0000,0x16cd,0x40,0x40,{{0x55,0x0f,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x400002,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}}, + {0x0000,0x16cd,0x40,0x40,{{0x55,0x0f,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x400002,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, /* Mahjong Lover */ - {0x0000,0x7037,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x401000,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}}, + {0x0000,0x7037,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0x400000,0x401000,0x000000,0x000000},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,0,NULL,NULL,default_regs_r,NULL}}, + {0x0080,0x3dba,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{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,0,NULL,NULL,default_regs_r,NULL}}, + {0x0000,0x1a28,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{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,0,NULL,NULL,default_regs_r,NULL}}, + {0xffff,0xd472,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,{{0x00,0x98,0xc9,0xF0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,0,NULL,NULL,default_regs_r,NULL}}, + {0x0000,0x0c5b,0x40,0x40,{{0x00,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,{{0xaa,0xa0,0xf0,0xa0},{0xfc0000,0xffffff,0xffffff,0xffffff},{0x480000,0x4c82c0,0x4cdda0,0x4f8820},0,0,0,NULL,NULL,default_regs_r,NULL}}, + {0x0000,0xd0a0,0x48,0x4f,{{0xaa,0xa0,0xf0,0xa0},{0xfc0000,0xffffff,0xffffff,0xffffff},{0x480000,0x4c82c0,0x4cdda0,0x4f8820},0,0,NULL,NULL,default_regs_r,NULL}}, /* Lian Huan Pao - Barver Battle Saga */ - {0x30b9,0x1c2a,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,0,NULL,NULL,default_regs_r,NULL}}, + {0x30b9,0x1c2a,0x40,0x40,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, /* Rockman X3 */ - {0x0000,0x9d0e,0x40,0x40,{{0x0c,0x88,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0xa13000,0x400004,0x000000,0x000000},0,0,0,default_regs_r,NULL,default_regs_r,NULL}}, + {0x0000,0x9d0e,0x40,0x40,{{0x0c,0x88,0x00,0x00},{0xffffff,0xffffff,0x000000,0x000000},{0xa13000,0x400004,0x000000,0x000000},0,0,default_regs_r,NULL,default_regs_r,NULL}}, /* Super Mario 2 1998 */ - {0xffff,0x0474,0x00,0x00,{{0x0a,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}}, + {0xffff,0x0474,0x00,0x00,{{0x0a,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, /* Super Mario 2 1998 */ - {0x2020,0xb4eb,0x00,0x00,{{0x1c,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}}, + {0x2020,0xb4eb,0x00,0x00,{{0x1c,0x00,0x00,0x00},{0xffffff,0x000000,0x000000,0x000000},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, /* A Bug's Life */ - {0x7f7f,0x2aad,0x00,0x00,{{0x28,0x1f,0x01,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}}, + {0x7f7f,0x2aad,0x00,0x00,{{0x28,0x1f,0x01,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, /* King of Fighter 99 */ - {0x0000,0x021e,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}}, + {0x0000,0x021e,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, /* Pocket Monster */ - {0xd6fc,0x1eb1,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,0,default_regs_r,NULL,NULL,NULL}}, + {0xd6fc,0x1eb1,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0x000000},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, /* Game no Kanzume Otokuyou */ - {0x0000,0xf9d1,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,0,NULL,seganet_mapper_w,NULL,NULL}} + {0x0000,0xf9d1,0x00,0x00,{{0x00,0x00,0x00,0x00},{0x000000,0x000000,0x000000,0x000000},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,seganet_mapper_w,NULL,NULL}} }; -/* temporary memory chunk */ -static uint8 mem_chunk[0x10000]; - /************************************************************ Cart Hardware initialization @@ -286,124 +283,15 @@ void cart_hw_init() m68k_memory_map[0x3a].read16 = svp_read_cell_2; } - /********************************************** - SPECIFIC CONTROLLER SETTINGS - ***********************************************/ - - /* restore previous settings */ - if (old_system[0] != -1) - input.system[0] = old_system[0]; - if (old_system[1] != -1) - input.system[1] = old_system[1]; - - /* initialize default GUN settings */ - input.x_offset = 0x00; - input.y_offset = 0x00; - - /********************************************** - SEGA MENACER - ***********************************************/ - 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]; - - input.system[0] = NO_SYSTEM; - input.system[1] = SYSTEM_MENACER; - input.x_offset = 0x52; - input.y_offset = 0x00; - } - 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]; - - input.system[0] = SYSTEM_GAMEPAD; - input.system[1] = SYSTEM_MENACER; - input.x_offset = 0x84; - input.y_offset = 0x08; - } - 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]; - - input.system[0] = SYSTEM_MOUSE; - input.system[1] = SYSTEM_MENACER; - input.x_offset = 0x44; - input.y_offset = 0x18; - } - - /********************************************** - KONAMI JUSTIFIER - ***********************************************/ - else if (strstr(rominfo.international,"LETHAL ENFORCERSII") != 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]; - - input.system[0] = SYSTEM_GAMEPAD; - input.system[1] = SYSTEM_JUSTIFIER; - input.x_offset = 0x18; - input.y_offset = 0x00; - } - else if (strstr(rominfo.international,"LETHAL ENFORCERS") != 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]; - - input.system[0] = SYSTEM_GAMEPAD; - input.system[1] = SYSTEM_JUSTIFIER; - input.x_offset = 0x00; - input.y_offset = 0x00; - } - /********************************************** J-CART ***********************************************/ - cart.hw.jcart = 0; - if (((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military*/ - ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */ - ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */ - ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x2c41)) || /* Micro Machines 96 (bad) */ - ((strstr(rominfo.product,"XXXXXXXX") != NULL) && (rominfo.checksum == 0xdf39)) || /* Sampras Tennis 96 */ - ((strstr(rominfo.product,"T-123456") != NULL) && (rominfo.checksum == 0x1eae)) || /* Sampras Tennis 96 */ - ((strstr(rominfo.product,"T-120066") != NULL) && (rominfo.checksum == 0x16a4)) || /* Pete Sampras Tennis (1994)*/ - (strstr(rominfo.product,"T-120096") != NULL)) /* Micro Machines 2 */ + if (cart.jcart) { - if (cart.romsize <= 0x380000) /* just to be sure (checksum might not be enough) */ - { - cart.hw.jcart = 1; - 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; - - /* 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]; - - /* set default settings */ - input.system[0] = SYSTEM_GAMEPAD; - input.system[1] = SYSTEM_GAMEPAD; - } + 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; } /********************************************** @@ -427,51 +315,51 @@ void cart_hw_init() break; case TYPE_SK: - /* be sure we have enough place to store both ROMs */ - if (cart.romsize < 0x700000) - { - /* load Sonic & Knuckles ROM (2 MBytes) */ - FILE *f = fopen(SK_ROM,"r+b"); - if (!f) break; - int done = 0; - while (done < 0x200000) - { - fread(cart.rom+0x700000+done,4096,1,f); - done += 4096; - } - fclose(f); + { + /* store S&K ROM above cartridge ROM + SRAM */ + if (cart.romsize > 0x600000) break; - /* load Sonic 2 UPMEM ROM (256 KBytes) */ - f = fopen(SK_UPMEM,"r+b"); - if (!f) break; - done = 0; - while (done < 0x40000) - { - fread(cart.rom+0x900000+done,4096,1,f); - done += 4096; - } - fclose(f); + /* load Sonic & Knuckles ROM (2 MBytes) */ + FILE *f = fopen(SK_ROM,"r+b"); + if (!f) break; + int done = 0; + while (done < 0x200000) + { + fread(cart.rom + 0x600000 + done, 2048, 1, f); + done += 2048; + } + fclose(f); + + /* load Sonic 2 UPMEM ROM (256 KBytes) */ + f = fopen(SK_UPMEM,"r+b"); + if (!f) break; + done = 0; + while (done < 0x40000) + { + fread(cart.rom + 0x800000 + done, 2048, 1, f); + done += 2048; + } + fclose(f); #ifdef LSB_FIRST - /* Byteswap ROM */ - int i; - uint8 temp; - for(i = 0; i < 0x240000; i += 2) - { - temp = cart.rom[i+0x700000]; - cart.rom[i+0x700000] = cart.rom[i+1+0x700000]; - cart.rom[i+1+0x700000] = temp; - } + /* Byteswap ROM */ + int i; + uint8 temp; + for(i = 0; i < 0x240000; i += 2) + { + temp = cart.rom[i + 0x600000]; + cart.rom[i + 0x600000] = cart.rom[i + 0x600000 + 1]; + cart.rom[i + 0x600000 + 1] = temp; + } #endif - /*$000000-$1fffff is mapped to S&K ROM */ - for (i=0x00; i<0x20; i++) - m68k_memory_map[i].base = (cart.rom + 0x700000) + (i<<16); + /*$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.lock_on = 1; - - } + cart.lock_on = 1; break; + } default: break; @@ -487,7 +375,7 @@ void cart_hw_init() { /* known cart found ! */ if ((rominfo.checksum == rom_database[i].chk_1) && - (realchecksum == rom_database[i].chk_2)) + (rominfo.realchecksum == rom_database[i].chk_2)) { /* retrieve hardware information */ memcpy(&cart.hw, &(rom_database[i].cart_hw), sizeof(T_CART_HW)); @@ -521,7 +409,7 @@ void cart_hw_init() emulate_address_error = config.addr_error; #endif - /* detect ROM files larger than 4MB */ + /* detect special cartridges */ if (cart.romsize > 0x800000) { /* Ultimate MK3 (hack) */ @@ -546,7 +434,6 @@ void cart_hw_init() } /* default write handler for !TIME signal */ - /* TODO: handle Sonic & Knuckles + Sonic 2 case to prevent RAM activation */ if (!cart.hw.time_w) cart.hw.time_w = default_time_w; } @@ -567,10 +454,10 @@ void cart_hw_reset() if (cart.hw.realtec & 1) { /* enable BOOTROM */ - for (i=0x00; i<0x40; i++) - m68k_memory_map[i].base = mem_chunk; for (i=0; i<8; i++) - memcpy(mem_chunk + i*0x2000, cart.rom + 0x7e000, 0x2000); + memcpy(cart.rom + 0x900000 + i*0x2000, cart.rom + 0x7e000, 0x2000); + for (i=0x00; i<0x40; i++) + m68k_memory_map[i].base = cart.rom + 0x900000; cart.hw.realtec |= 2; } @@ -657,7 +544,7 @@ static void sega_mapper_w(uint32 address, uint32 data) { /* enable UPMEM chip at $300000-$3fffff */ for (i=0x30; i<0x40; i++) - m68k_memory_map[i].base = (cart.rom + 0x900000) + ((i & 3)<<16); + m68k_memory_map[i].base = (cart.rom + 0x800000) + ((i & 3)<<16); } } else @@ -708,9 +595,9 @@ static void multi_mapper_w(uint32 address, uint32 data) static void special_mapper_w(uint32 address, uint32 data) { /* 1 x 32k bank */ - m68k_memory_map[0].base = mem_chunk; - memcpy(mem_chunk,&cart.rom[(data & 0x7f) << 15],0x8000); - memcpy(mem_chunk+0x8000,cart.rom + 0x8000,0x8000); + memcpy(cart.rom + 0x900000, cart.rom + ((data & 0x7f) << 15), 0x8000); + memcpy(cart.rom + 0x908000, cart.rom + 0x8000, 0x8000); + m68k_memory_map[0].base = cart.rom + 0x900000; } /* diff --git a/source/cart_hw/cart_hw.h b/source/cart_hw/cart_hw.h index a60c309..d1119a5 100644 --- a/source/cart_hw/cart_hw.h +++ b/source/cart_hw/cart_hw.h @@ -38,8 +38,7 @@ typedef struct uint8 regs[4]; /* internal registers (R/W) */ uint32 mask[4]; /* registers address mask */ uint32 addr[4]; /* registers address */ - uint32 realtec; /* bit 0: realtec mapper detected, bit 1: bootrom enabled */ - uint16 jcart; /* cartridge with JCART port */ + uint16 realtec; /* bit 0: realtec mapper detected, bit 1: bootrom enabled */ uint16 bankshift; /* cartridge with bankshift mecanism */ 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 */ @@ -51,11 +50,12 @@ typedef struct typedef struct { uint8 *rom; /* ROM data */ - uint8 *base; /* ROM area (slot 0) */ - uint32 mask; /* mask ROM */ - uint32 lock_on; /* 1: Lock-On enabled */ + uint8 *base; /* ROM base area (slot 0) */ uint32 romsize; /* ROM size */ - T_CART_HW hw; /* Custom hardware */ + uint32 mask; /* mask ROM */ + uint16 lock_on; /* 1: Lock-On enabled */ + uint16 jcart; /* 1: J-CART port enabled */ + T_CART_HW hw; /* Extra hardware */ } T_CART; /* global variables */ diff --git a/source/cart_hw/datel.c b/source/cart_hw/datel.c index def9cc9..455fb3e 100644 --- a/source/cart_hw/datel.c +++ b/source/cart_hw/datel.c @@ -27,8 +27,8 @@ struct { uint8 enabled; - uint8 rom[0x20000]; - uint8 ram[0x10000]; + uint8 *rom; + uint8 *ram; uint16 regs[13]; uint16 old[4]; uint16 data[4]; @@ -49,6 +49,11 @@ void datel_init(void) if (!f) return; + /* store Action replay ROM + RAM above cartridge ROM + SRAM */ + if (cart.romsize > 0x600000) return; + action_replay.rom = cart.rom + 0x600000; + action_replay.ram = cart.rom + 0x610000; + /* ROM size */ fseek(f, 0, SEEK_END); int size = ftell(f); @@ -59,9 +64,6 @@ void datel_init(void) case 0x8000: /* ACTION REPLAY (32K) */ { action_replay.enabled = TYPE_AR; - - /* $0000-$7fff mirrored into $8000-$ffff */ - memcpy(action_replay.rom+0x8000,action_replay.rom,0x8000); break; } @@ -92,33 +94,32 @@ void datel_init(void) } default: + { + fclose(f); return; + } } - if (action_replay.enabled) + /* Load ROM */ + fseek(f, 0, SEEK_SET); + int i = 0; + while (i < size) { - /* Load ROM */ - fseek(f, 0, SEEK_SET); - int i = 0; - while (i < size) - { - fread(action_replay.rom+i,0x1000,1,f); - i += 0x1000; - } + fread(action_replay.rom+i,0x1000,1,f); + i += 0x1000; + } + fclose(f); #ifdef LSB_FIRST - /* Byteswap ROM */ - uint8 temp; - for(i = 0; i < size; i += 2) - { - temp = action_replay.rom[i]; - action_replay.rom[i] = action_replay.rom[i+1]; - action_replay.rom[i+1] = temp; - } -#endif + /* Byteswap ROM */ + uint8 temp; + for(i = 0; i < size; i += 2) + { + temp = action_replay.rom[i]; + action_replay.rom[i] = action_replay.rom[i+1]; + action_replay.rom[i+1] = temp; } - - fclose(f); +#endif } void datel_shutdown(void) @@ -178,7 +179,7 @@ void datel_reset(int hard_reset) /* clear RAM on hard reset only */ if (hard_reset) - memset(action_replay.ram,0,sizeof(action_replay.ram)); + memset(action_replay.ram,0,0x10000); } void datel_switch(int enable) diff --git a/source/cart_hw/eeprom.c b/source/cart_hw/eeprom.c index 2b53c48..aaac2f5 100644 --- a/source/cart_hw/eeprom.c +++ b/source/cart_hw/eeprom.c @@ -111,14 +111,12 @@ void eeprom_init() } /* Game not found in database but header seems to indicate it uses EEPROM */ - if (!sram.custom) + if (sram.detected && !sram.custom) { if ((sram.end - sram.start) < 2) { - sram.custom = 1; - sram.on = 1; - /* set SEGA mapper as default */ + sram.custom = 1; memcpy(&eeprom.type, &database[9].type, sizeof(T_EEPROM_TYPE)); } } diff --git a/source/cart_hw/ggenie.c b/source/cart_hw/ggenie.c index 37a8151..e4b89fe 100644 --- a/source/cart_hw/ggenie.c +++ b/source/cart_hw/ggenie.c @@ -27,7 +27,7 @@ static struct { uint8 enabled; - uint8 rom[0x10000]; + uint8 *rom; uint16 regs[0x20]; uint16 old[6]; uint16 data[6]; @@ -47,6 +47,10 @@ void ggenie_init(void) FILE *f = fopen(GG_ROM,"rb"); if (!f) return; + /* store Game Genie ROM above cartridge ROM + SRAM */ + if (cart.romsize > 0x600000) return; + ggenie.rom = cart.rom + 0x600000; + /* Load ROM */ int i = 0; while (i < 0x8000) diff --git a/source/cart_hw/sram.c b/source/cart_hw/sram.c index f2f86b9..1d5fbb9 100644 --- a/source/cart_hw/sram.c +++ b/source/cart_hw/sram.c @@ -42,33 +42,41 @@ T_SRAM sram; void sram_init() { memset (&sram, 0, sizeof (T_SRAM)); - memset (&sram.sram[0], 0xFF, 0x10000); - sram.crc = crc32(0, &sram.sram[0], 0x10000); + /* store SRAM into cartridge area */ + if (cart.romsize > 0x500000) return; + sram.sram = cart.rom + 0x500000; + + /* initialize SRAM */ + 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)) { - /* retrieve informations from headezr */ - sram.detected = 1; sram.start = READ_WORD_LONG(cart.rom, 0x1b4); sram.end = READ_WORD_LONG(cart.rom, 0x1b8); /* fixe some bad header informations */ if ((sram.start > sram.end) || ((sram.end - sram.start) >= 0x10000)) - sram.end = sram.start + 0xffff; + sram.end = sram.start + 0xffff; sram.start &= 0xfffffffe; sram.end |= 1; + + /* enable SRAM */ sram.on = 1; + sram.detected = 1; } - else + else { /* default SRAM region */ sram.start = 0x200000; sram.end = 0x20ffff; - } - /* set SRAM ON by default when ROM is not mapped */ - if (cart.romsize <= sram.start) - sram.on = 1; + /* enable SRAM only if ROM < 2MB */ + if (cart.romsize <= sram.start) + sram.on = 1; + } /* autodetect some games with bad header or specific configuration */ if (strstr(rominfo.product,"T-113016") != NULL) @@ -119,7 +127,8 @@ void sram_init() sram.start = 0x200001; sram.end = 0x203fff; } - else if (((realchecksum == 0xaeaa) || (realchecksum == 0x8dba)) && (rominfo.checksum == 0x8104)) + else if (((rominfo.realchecksum == 0xaeaa) || (rominfo.realchecksum == 0x8dba)) && + (rominfo.checksum == 0x8104)) { /* Xin Qigai Wangzi, aka Beggar Prince (no header, use uncommon area) */ sram.on = 1; diff --git a/source/cart_hw/sram.h b/source/cart_hw/sram.h index 4dd21e8..daf6118 100644 --- a/source/cart_hw/sram.h +++ b/source/cart_hw/sram.h @@ -31,7 +31,7 @@ typedef struct uint32 start; uint32 end; uint32 crc; - uint8 sram[0x10000]; + uint8 *sram; } T_SRAM; /* Function prototypes */ diff --git a/source/gen_input.c b/source/gen_input.c index 88eba3c..7e6aaf5 100644 --- a/source/gen_input.c +++ b/source/gen_input.c @@ -24,6 +24,7 @@ #include "shared.h" t_input input; +int old_system[2] = {-1,-1}; /************************************************************************************/ /* */ @@ -70,7 +71,7 @@ static const uint8 hc_256[171] = }; /***************************************************************************** - * LIGHTGUN specific functions + * LIGHTGUN support * *****************************************************************************/ static inline void lightgun_reset(int num) @@ -146,7 +147,7 @@ uint32 justifier_read(void) } /***************************************************************************** - * SEGA MOUSE specific functions + * SEGA MOUSE support * *****************************************************************************/ static struct mega_mouse @@ -268,7 +269,7 @@ uint32 mouse_read() /***************************************************************************** - * GAMEPAD specific functions (2PLAYERS/4WAYPLAY) + * GAMEPAD support (2PLAYERS/4WAYPLAY) * *****************************************************************************/ static struct pad @@ -297,15 +298,15 @@ static inline void gamepad_update(uint32 i) static inline uint32 gamepad_read(uint32 i) { - int control; + /* bit7 is latched */ int retval = 0x7F; - control = (gamepad[i].State & 0x40) >> 6; /* current TH state */ + /* current TH state */ + int control = (gamepad[i].State & 0x40) >> 6; + /* TH transitions counter */ if (input.dev[i] == DEVICE_6BUTTON) - { - control += (gamepad[i].Counter & 3) << 1; /* TH transitions counter */ - } + control += (gamepad[i].Counter & 3) << 1; switch (control) { @@ -376,7 +377,6 @@ static inline uint32 gamepad_read(uint32 i) break; } - /* bit7 is latched */ return retval; } @@ -397,7 +397,7 @@ static inline void gamepad_write(uint32 i, uint32 data) /***************************************************************************** - * TEAMPLAYER adapter + * TEAMPLAYER adapter support * *****************************************************************************/ static struct teamplayer @@ -536,7 +536,7 @@ static inline void teamplayer_write(uint32 port, uint32 data) } /***************************************************************************** - * 4WAYPLAY adapter + * 4-WAYPLAY adapter support * *****************************************************************************/ static inline void wayplay_write(uint32 port, uint32 data) @@ -619,7 +619,8 @@ void teamplayer_2_write (uint32 data) uint32 jcart_read(uint32 address) { - return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8)); /* fixes Micro Machines 2 */ + /* TH2 (output) fixed to 0 on read (fixes Micro Machines 2) */ + return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8)); } void jcart_write(uint32 address, uint32 data) @@ -719,7 +720,7 @@ void input_init(void) } /* J-CART: add two gamepad inputs */ - if (cart.hw.jcart) + if (cart.jcart) { input.dev[5] = config.input[2].padtype; input.dev[6] = config.input[3].padtype; @@ -767,13 +768,15 @@ void input_update(void) switch (input.system[0]) { case SYSTEM_GAMEPAD: - if (input.dev[0] == DEVICE_6BUTTON) gamepad_update(0); + if (input.dev[0] == DEVICE_6BUTTON) + gamepad_update(0); break; case SYSTEM_WAYPLAY: for (i=0; i<4; i++) { - if (input.dev[i] == DEVICE_6BUTTON) gamepad_update(i); + if (input.dev[i] == DEVICE_6BUTTON) + gamepad_update(i); } break; } @@ -781,7 +784,8 @@ void input_update(void) switch (input.system[1]) { case SYSTEM_GAMEPAD: - if (input.dev[4] == DEVICE_6BUTTON) gamepad_update(4); + if (input.dev[4] == DEVICE_6BUTTON) + gamepad_update(4); break; case SYSTEM_MENACER: @@ -789,8 +793,10 @@ void input_update(void) break; case SYSTEM_JUSTIFIER: - if ((io_reg[2] & 0x30) == 0x00) lightgun_update(0); - if ((io_reg[2] & 0x30) == 0x20) lightgun_update(1); + if ((io_reg[2] & 0x30) == 0x00) + lightgun_update(0); + if ((io_reg[2] & 0x30) == 0x20) + lightgun_update(1); break; } } @@ -801,13 +807,15 @@ void input_raz(void) switch (input.system[0]) { case SYSTEM_GAMEPAD: - if (input.dev[0] == DEVICE_6BUTTON) gamepad_raz(0); + if (input.dev[0] == DEVICE_6BUTTON) + gamepad_raz(0); break; case SYSTEM_WAYPLAY: for (i=0; i<4; i++) { - if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i); + if (input.dev[i] == DEVICE_6BUTTON) + gamepad_raz(i); } break; } @@ -815,7 +823,123 @@ void input_raz(void) switch (input.system[1]) { case SYSTEM_GAMEPAD: - if (input.dev[4] == DEVICE_6BUTTON) gamepad_raz(4); + if (input.dev[4] == DEVICE_6BUTTON) + gamepad_raz(4); break; } } + +void input_autodetect(void) +{ + /* restore previous settings */ + if (old_system[0] != -1) + input.system[0] = old_system[0]; + if (old_system[1] != -1) + input.system[1] = old_system[1]; + + /* initialize default GUN settings */ + input.x_offset = 0x00; + input.y_offset = 0x00; + + /********************************************** + SEGA MENACER + ***********************************************/ + 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]; + + input.system[0] = NO_SYSTEM; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 0x52; + input.y_offset = 0x00; + } + 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]; + + input.system[0] = SYSTEM_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 0x84; + input.y_offset = 0x08; + } + 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]; + + input.system[0] = SYSTEM_MOUSE; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 0x44; + input.y_offset = 0x18; + } + + /********************************************** + KONAMI JUSTIFIER + ***********************************************/ + else if (strstr(rominfo.international,"LETHAL ENFORCERSII") != 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]; + + input.system[0] = SYSTEM_GAMEPAD; + input.system[1] = SYSTEM_JUSTIFIER; + input.x_offset = 0x18; + input.y_offset = 0x00; + } + else if (strstr(rominfo.international,"LETHAL ENFORCERS") != 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]; + + input.system[0] = SYSTEM_GAMEPAD; + input.system[1] = SYSTEM_JUSTIFIER; + input.x_offset = 0x00; + input.y_offset = 0x00; + } + + /********************************************** + J-CART + ***********************************************/ + cart.jcart = 0; + if (((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military*/ + ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */ + ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */ + ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x2c41)) || /* Micro Machines 96 (bad) */ + ((strstr(rominfo.product,"XXXXXXXX") != NULL) && (rominfo.checksum == 0xdf39)) || /* Sampras Tennis 96 */ + ((strstr(rominfo.product,"T-123456") != NULL) && (rominfo.checksum == 0x1eae)) || /* Sampras Tennis 96 */ + ((strstr(rominfo.product,"T-120066") != NULL) && (rominfo.checksum == 0x16a4)) || /* Pete Sampras Tennis (1994)*/ + (strstr(rominfo.product,"T-120096") != NULL)) /* Micro Machines 2 */ + { + if (cart.romsize <= 0x380000) /* just to be sure (checksum might not be enough) */ + { + cart.jcart = 1; + + /* 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]; + + /* set default settings */ + input.system[0] = SYSTEM_GAMEPAD; + input.system[1] = SYSTEM_GAMEPAD; + } + } +} diff --git a/source/gen_input.h b/source/gen_input.h index 7c3dd97..b8538ec 100644 --- a/source/gen_input.h +++ b/source/gen_input.h @@ -78,6 +78,7 @@ extern void input_init(void); extern void input_reset(void); extern void input_update(void); extern void input_raz(void); +extern void input_autodetect(void); /* Peripherals specific */ extern void mouse_write(uint32 data); diff --git a/source/gen_io.c b/source/gen_io.c index 68ef1ca..996092d 100644 --- a/source/gen_io.c +++ b/source/gen_io.c @@ -25,7 +25,6 @@ uint8 io_reg[0x10]; uint8 region_code = REGION_USA; -int old_system[2] = {-1,-1}; static struct port_t { @@ -117,20 +116,24 @@ void io_init(void) void io_reset(void) { - /* I/O register default settings */ - uint8 io_def[0x10] = - { - 0xA0, - 0x7F, 0x7F, 0x7F, - 0x00, 0x00, 0x00, - 0xFF, 0x00, 0x00, - 0xFF, 0x00, 0x00, - 0xFB, 0x00, 0x00, - }; - /* Reset I/O registers */ - memcpy (io_reg, io_def, 0x10); - + io_reg[0x00] = region_code | 0x20 | (config.bios_enabled == 3); + io_reg[0x01] = 0x7F; + io_reg[0x02] = 0x7F; + io_reg[0x03] = 0x7F; + 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; + /* Reset connected input devices */ input_reset(); } @@ -142,29 +145,16 @@ void io_write(uint32 offset, uint32 value) case 0x01: /* Port A Data */ case 0x02: /* Port B Data */ case 0x03: /* Port C Data */ - io_reg[offset] = ((value & 0x80) | (value & io_reg[offset+3])); - if(port[offset-1].data_w) port[offset-1].data_w(value); + io_reg[offset] = value & (0x80 | io_reg[offset+3]); + if(port[offset-1].data_w) + port[offset-1].data_w(value); return; - case 0x05: /* Port B Ctrl */ - if (((value & 0x7F) == 0x7F) && - ((input.system[0] == SYSTEM_TEAMPLAYER) || - (input.system[1] == SYSTEM_TEAMPLAYER))) - { - /* autodetect 4-Way play ! */ - input.system[0] = SYSTEM_WAYPLAY; - input.system[1] = SYSTEM_WAYPLAY; - port[0].data_w = wayplay_1_write; - port[0].data_r = wayplay_1_read; - port[1].data_w = wayplay_2_write; - port[1].data_r = wayplay_2_read; - input_reset(); - } - case 0x04: /* Port A Ctrl */ + case 0x05: /* Port B Ctrl */ case 0x06: /* Port C Ctrl */ - io_reg[offset] = value & 0xFF; - io_reg[offset-3] = ((io_reg[offset-3] & 0x80) | (io_reg[offset-3] & io_reg[offset])); + io_reg[offset] = value; + io_reg[offset-3] &= (0x80 | value); return; case 0x07: /* Port A TxData */ @@ -176,7 +166,10 @@ void io_write(uint32 offset, uint32 value) case 0x09: /* Port A S-Ctrl */ case 0x0C: /* Port B S-Ctrl */ case 0x0F: /* Port C S-Ctrl */ - io_reg[offset] = (value & 0xF8); + io_reg[offset] = value & 0xF8; + return; + + default: /* Read-only ports */ return; } } @@ -185,23 +178,17 @@ uint32 io_read(uint32 offset) { switch(offset) { - case 0x00: /* Version register */ - { - uint8 has_scd = 0x20; /* No Sega CD unit attached */ - uint8 gen_ver = (config.bios_enabled == 3) ? 0x01 : 0x00; /* hardware version */ - return (region_code | has_scd | gen_ver); - } - case 0x01: /* Port A Data */ case 0x02: /* Port B Data */ case 0x03: /* Port C Data */ { - uint8 input = 0x7F; /* default input state */ - if(port[offset-1].data_r) input = port[offset-1].data_r(); + uint8 input = 0x7F; + if(port[offset-1].data_r) + input = port[offset-1].data_r(); return (io_reg[offset] | ((~io_reg[offset+3]) & input)); } - default: + default: /* return register value */ return (io_reg[offset]); } } diff --git a/source/genesis.c b/source/genesis.c index be7041a..2333399 100644 --- a/source/genesis.c +++ b/source/genesis.c @@ -30,15 +30,10 @@ uint32 zirq; /* /IRQ to Z80 */ uint32 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */ uint32 zbank; /* Z80 bank window address */ uint32 gen_running; /* 0: cpu are in locked state */ -int32 resetline; /* soft reset is triggered on a random line (X-Men 2, Eternal Champions) */ /*--------------------------------------------------------------------------*/ /* Init, reset, shutdown functions */ /*--------------------------------------------------------------------------*/ -void set_softreset(void) -{ - resetline = (int) ((double) (lines_per_frame - 1) * rand() / (RAND_MAX + 1.0)); -} void gen_init(void) { @@ -138,13 +133,17 @@ void gen_reset(uint32 hard_reset) mcycles_68k = 0; mcycles_z80 = 0; } + else + { + /* VDP is not reseted so CPU could be anywhere in a frame */ + mcycles_68k = mcycles_z80 = (uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX)); + } zstate = 0; /* Z80 is reset & has control of the bus */ zirq = 0; /* No interrupts occuring */ zbank = 0; /* Assume default bank is $000000-$007FFF */ /* Reset CPUs */ - resetline = -1; gen_running = 1; fm_reset(0); m68k_pulse_reset(); diff --git a/source/gx/config.c b/source/gx/config.c index 26359a5..8f144ae 100644 --- a/source/gx/config.c +++ b/source/gx/config.c @@ -134,7 +134,7 @@ void config_default(void) sprintf (config.sddir, "sd:%s/roms/", DEFAULT_PATH); sprintf (config.usbdir, "usb:%s/roms/", DEFAULT_PATH); #else - sprintf (config.sddir, "/%s/roms/", DEFAULT_PATH); + sprintf (config.sddir, "%s/roms/", DEFAULT_PATH); #endif /* restore from config file */ diff --git a/source/gx/fileio/file_dvd.c b/source/gx/fileio/file_dvd.c index 6e95001..c1c6d4a 100644 --- a/source/gx/fileio/file_dvd.c +++ b/source/gx/fileio/file_dvd.c @@ -308,9 +308,16 @@ int DVD_LoadFile(u8 *buffer, u32 selection) /* determine file type */ if (!IsZipFile ((char *) readbuffer)) { - char msg[50]; + if (length > MAXROMSIZE) + { + GUI_WaitPrompt("Error","File size not supported !"); + return 0; + } + + char msg[64]; sprintf(msg,"Loading %d bytes...", length); GUI_MsgBoxOpen("Information",msg,1); + /* How many 2k blocks to read */ int blocks = length / DVDCHUNK; int readoffset = 0; @@ -373,7 +380,7 @@ int DVD_Open(void) while(DI_GetStatus() & DVD_INIT) usleep(10); if (!(DI_GetStatus() & DVD_READY)) { - char msg[50]; + char msg[64]; sprintf(msg, "DI Status Error: 0x%08X !\n",DI_GetStatus()); GUI_WaitPrompt("Error",msg); return 0; diff --git a/source/gx/fileio/file_fat.c b/source/gx/fileio/file_fat.c index 7af3dc0..c1d456c 100644 --- a/source/gx/fileio/file_fat.c +++ b/source/gx/fileio/file_fat.c @@ -55,7 +55,7 @@ int FAT_UpdateDirectory(bool go_up, char *dirname) { int size=0; char *test; - char temp[1024]; + char temp[MAXPATHLEN]; /* go up to parent directory */ if (strcmp(dirname,"..") == 0) @@ -185,11 +185,17 @@ int FAT_LoadFile(u8 *buffer, u32 selection) /* Determine file type */ if (!IsZipFile ((char *) temp)) { + if (length > MAXROMSIZE) + { + GUI_WaitPrompt("Error","File size not supported !"); + return 0; + } + /* re-open and read file */ sdfile = fopen(fname, "rb"); if (sdfile) { - char msg[50]; + char msg[64]; sprintf(msg,"Loading %d bytes ...", length); GUI_MsgBoxOpen("Information",msg,1); int done = 0; @@ -235,7 +241,7 @@ int FAT_Open(int type) filelist[i].offset = 0; filelist[i].length = 0; filelist[i].flags = 0; - strncpy(filelist[i].filename, history.entries[i].filename, MAXJOLIET-1); + strncpy(filelist[i].filename,history.entries[i].filename, MAXJOLIET-1); filelist[i].filename[MAXJOLIET-1] = '\0'; max++; } diff --git a/source/gx/fileio/file_slot.c b/source/gx/fileio/file_slot.c index 3548e4e..84c03fe 100644 --- a/source/gx/fileio/file_slot.c +++ b/source/gx/fileio/file_slot.c @@ -35,13 +35,6 @@ */ static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32); -/** - * DMA Transfer Area. - * Must be 32-byte aligned. - * 64k SRAM + 2k Icon - */ -static u8 savebuffer[STATE_SIZE] ATTRIBUTE_ALIGN (32); - /**************************************************************************** * CardMount @@ -139,9 +132,9 @@ void slot_autodetect(int slot, int device, t_slot *ptr) { /* Memory Card support */ if (slot > 0) - sprintf(filename,"MD-%04X.gp%d", realchecksum, slot - 1); + sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1); else - sprintf(filename,"MD-%04X.srm", realchecksum); + sprintf(filename,"MD-%04X.srm", rominfo.realchecksum); /* Initialise the CARD system */ memset(&SysArea, 0, CARD_WORKAREA); @@ -201,9 +194,9 @@ int slot_delete(int slot, int device) { /* Memory Card support */ if (slot > 0) - sprintf(filename,"MD-%04X.gp%d", realchecksum, slot - 1); + sprintf(filename,"MD-%04X.gp%d", rominfo.realchecksum, slot - 1); else - sprintf(filename,"MD-%04X.srm", realchecksum); + sprintf(filename,"MD-%04X.srm", rominfo.realchecksum); /* Initialise the CARD system */ memset(&SysArea, 0, CARD_WORKAREA); @@ -228,15 +221,23 @@ int slot_load(int slot, int device) { char filename[MAXPATHLEN]; int filesize, done = 0; - int offset = device ? 2112 : 0; + int offset = 0; + u8 *savebuffer; if (slot > 0) + { GUI_MsgBoxOpen("Information","Loading State ...",1); + } else - GUI_MsgBoxOpen("Information","Loading SRAM ...",1); + { + if (!sram.on) + { + GUI_WaitPrompt("Error","SRAM is disabled !"); + return 0; + } - /* clean buffer */ - memset(savebuffer, 0, STATE_SIZE); + GUI_MsgBoxOpen("Information","Loading SRAM ...",1); + } if (!device) { @@ -248,42 +249,49 @@ int slot_load(int slot, int device) /* Open file */ FILE *fp = fopen(filename, "rb"); - if (fp) - { - /* Read size */ - fseek(fp, 0, SEEK_END); - filesize = ftell(fp); - fseek(fp, 0, SEEK_SET); - - /* Read into buffer (2k blocks) */ - while (filesize > FATCHUNK) - { - fread(savebuffer + done, FATCHUNK, 1, fp); - done += FATCHUNK; - filesize -= FATCHUNK; - } - - /* Read remaining bytes */ - fread(savebuffer + done, filesize, 1, fp); - done += filesize; - fclose(fp); - } - else + if (!fp) { GUI_WaitPrompt("Error","Unable to open file !"); return 0; } + + /* Read size */ + fseek(fp, 0, SEEK_END); + filesize = ftell(fp); + fseek(fp, 0, SEEK_SET); + + /* allocate buffer */ + savebuffer = (u8 *)memalign(32,filesize); + if (!savebuffer) + { + GUI_WaitPrompt("Error","Unable to allocate memory !"); + fclose(fp); + return 0; + } + + /* Read into buffer (2k blocks) */ + while (filesize > FATCHUNK) + { + fread(savebuffer + done, FATCHUNK, 1, fp); + done += FATCHUNK; + filesize -= FATCHUNK; + } + + /* Read remaining bytes */ + fread(savebuffer + done, filesize, 1, fp); + done += filesize; + fclose(fp); } else { /* Memory Card support */ if (slot > 0) - sprintf(filename, "MD-%04X.gp%d", realchecksum, slot - 1); + sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1); else - sprintf(filename, "MD-%04X.srm", realchecksum); + sprintf(filename, "MD-%04X.srm", rominfo.realchecksum); /* Initialise the CARD system */ - char action[80]; + char action[64]; memset(&SysArea, 0, CARD_WORKAREA); CARD_Init("GENP", "00"); @@ -291,53 +299,60 @@ int slot_load(int slot, int device) device--; /* Attempt to mount the card */ - if (CardMount(device)) - { - /* Retrieve the sector size */ - u32 SectorSize = 0; - int CardError = CARD_GetSectorSize(device, &SectorSize); - if (SectorSize > 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; - - /* Read file sectors */ - while (filesize > 0) - { - CARD_Read(&CardFile, &savebuffer[done], SectorSize, done); - done += SectorSize; - filesize -= SectorSize; - } - - CARD_Close(&CardFile); - CARD_Unmount(device); - } - else - { - sprintf(action, "Invalid sector size (%d)", CardError); - GUI_WaitPrompt("Error",action); - CARD_Unmount(device); - return 0; - } - } - else + 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; + } + + /* Retrieve file size */ + filesize = CardFile.len; + if (filesize % SectorSize) + filesize = ((filesize / SectorSize) + 1) * SectorSize; + + /* Allocate buffer */ + savebuffer = (u8 *)memalign(32,filesize); + if (!savebuffer) + { + GUI_WaitPrompt("Error","Unable to allocate memory !"); + CARD_Close(&CardFile); + CARD_Unmount(device); + return 0; + } + + /* Read file sectors */ + while (filesize > 0) + { + CARD_Read(&CardFile, &savebuffer[done], SectorSize, done); + done += SectorSize; + filesize -= SectorSize; + } + + CARD_Close(&CardFile); + CARD_Unmount(device); + offset = 2112; } if (slot > 0) @@ -345,7 +360,8 @@ int slot_load(int slot, int device) /* Load state */ if (!state_load(&savebuffer[offset])) { - GUI_WaitPrompt("Error","Version is not compatible !"); + free(savebuffer); + GUI_WaitPrompt("Error","Unable to load state !"); return 0; } } @@ -353,9 +369,10 @@ int slot_load(int slot, int device) { /* Load SRAM & update CRC */ memcpy(sram.sram, &savebuffer[offset], 0x10000); - sram.crc = crc32(0, &sram.sram[0], 0x10000); + sram.crc = crc32(0, sram.sram, 0x10000); } + free(savebuffer); GUI_MsgBoxClose(); return 1; } @@ -366,20 +383,40 @@ int slot_save(int slot, int device) char filename[MAXPATHLEN]; int filesize, done = 0; int offset = device ? 2112 : 0; - - /* clean buffer */ - memset(savebuffer, 0, STATE_SIZE); + u8 *savebuffer; if (slot > 0) { + /* allocate buffer */ + savebuffer = (u8 *)memalign(32,STATE_SIZE); + if (!savebuffer) + { + GUI_WaitPrompt("Error","Unable to allocate memory !"); + return 0; + } + GUI_MsgBoxOpen("Information","Saving State ...",1); filesize = state_save(&savebuffer[offset]); } else { + if (!sram.on) + { + GUI_WaitPrompt("Error","SRAM is disabled !"); + return 0; + } + + /* allocate buffer */ + savebuffer = (u8 *)memalign(32,0x10000+offset); + if (!savebuffer) + { + GUI_WaitPrompt("Error","Unable to allocate memory !"); + return 0; + } + GUI_MsgBoxOpen("Information","Saving SRAM ...",1); memcpy(&savebuffer[offset], sram.sram, 0x10000); - sram.crc = crc32(0, &sram.sram[0], 0x10000); + sram.crc = crc32(0, sram.sram, 0x10000); filesize = 0x10000; } @@ -393,44 +430,36 @@ int slot_save(int slot, int device) /* Open file */ FILE *fp = fopen(filename, "wb"); - if (fp) - { - /* Read into buffer (2k blocks) */ - while (filesize > FATCHUNK) - { - fwrite(savebuffer + done, FATCHUNK, 1, fp); - done += FATCHUNK; - filesize -= FATCHUNK; - } - - /* Write remaining bytes */ - fwrite(savebuffer + done, filesize, 1, fp); - done += filesize; - fclose(fp); - - if (slot) - { - /* save screenshot */ - sprintf(filename,"%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1); - gxSaveScreenshot(filename); - } - } - else + if (!fp) { GUI_WaitPrompt("Error","Unable to open file !"); + free(savebuffer); return 0; } - } + + /* Read into buffer (2k blocks) */ + while (filesize > FATCHUNK) + { + fwrite(savebuffer + done, FATCHUNK, 1, fp); + done += FATCHUNK; + filesize -= FATCHUNK; + } + + /* Write remaining bytes */ + fwrite(savebuffer + done, filesize, 1, fp); + done += filesize; + fclose(fp); + } else { /* Memory Card support */ if (slot > 0) - sprintf(filename, "MD-%04X.gp%d", realchecksum, slot - 1); + sprintf(filename, "MD-%04X.gp%d", rominfo.realchecksum, slot - 1); else - sprintf(filename, "MD-%04X.srm", realchecksum); + sprintf(filename, "MD-%04X.srm", rominfo.realchecksum); /* Initialise the CARD system */ - char action[80]; + char action[64]; memset(&SysArea, 0, CARD_WORKAREA); CARD_Init("GENP", "00"); @@ -438,102 +467,112 @@ int slot_save(int slot, int device) device--; /* Attempt to mount the card */ - if (CardMount(device)) + if (!CardMount(device)) { - /* Retrieve the sector size */ - u32 SectorSize = 0; - int CardError = CARD_GetSectorSize(device, &SectorSize); - if (SectorSize) + GUI_WaitPrompt("Error","Unable to mount memory card"); + free(savebuffer); + 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); + free(savebuffer); + return 0; + } + + /* Build the output buffer */ + char comment[2][32] = { {"Genesis Plus GX"}, {"SRAM Save"} }; + strcpy (comment[1], filename); + memcpy (&savebuffer[0], &icon, 2048); + memcpy (&savebuffer[2048], &comment[0], 64); + + /* Adjust file size */ + filesize += 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) { - /* Build the output buffer */ - char comment[2][32] = { {"Genesis Plus GX"}, {"SRAM Save"} }; - strcpy (comment[1], filename); - memcpy (&savebuffer[0], &icon, 2048); - memcpy (&savebuffer[2048], &comment[0], 64); - - /* Adjust file size */ - filesize += 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)); - if (size > 0) - { - /* new file is bigger: check if there is enough space left */ - CardError = CARD_Create(device, "TEMP", size, &CardFile); - if (CardError) - { - sprintf(action, "Not enough memory space left (%d)", CardError); - GUI_WaitPrompt("Error",action); - CARD_Unmount(device); - return 0; - } - CARD_Close(&CardFile); - memset(&CardFile,0,sizeof(CardFile)); - CARD_Delete(device, "TEMP"); - } - - /* delete previously existing slot */ - CARD_Delete(device, filename); - } - - /* Create a new slot */ - CardError = CARD_Create(device, filename, filesize, &CardFile); + CardError = CARD_Create(device, "TEMP", size, &CardFile); if (CardError) { - sprintf(action, "Unable to create file (%d)", CardError); + sprintf(action, "Unable to increase file size (%d)", CardError); GUI_WaitPrompt("Error",action); CARD_Unmount(device); + free(savebuffer); return 0; } - /* Get current time */ - time_t rawtime; - time(&rawtime); - - /* Update file informations */ - 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, &savebuffer[done], SectorSize, done); - filesize -= SectorSize; - done += SectorSize; - } - - /* Close file */ + /* delete temporary file */ CARD_Close(&CardFile); - CARD_Unmount(device); - } - else - { - sprintf(action, "Invalid sector size (%d)", CardError); - GUI_WaitPrompt("Error",action); - CARD_Unmount(device); - return 0; + memset(&CardFile,0,sizeof(CardFile)); + CARD_Delete(device, "TEMP"); } + + /* delete previously existing file */ + CARD_Delete(device, filename); } - else + + /* Create a new file */ + CardError = CARD_Create(device, filename, filesize, &CardFile); + if (CardError) { - GUI_WaitPrompt("Error","Unable to mount memory card"); + sprintf(action, "Unable to create file (%d)", CardError); + GUI_WaitPrompt("Error",action); + CARD_Unmount(device); + free(savebuffer); 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, &savebuffer[done], SectorSize, done); + filesize -= SectorSize; + done += SectorSize; + } + + /* Close file */ + CARD_Close(&CardFile); + CARD_Unmount(device); } GUI_MsgBoxClose(); + free(savebuffer); + + /* Save screenshot */ + if (slot && !device) + { + sprintf(filename,"%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1); + gxSaveScreenshot(filename); + } + return 1; } diff --git a/source/gx/fileio/unzip.c b/source/gx/fileio/unzip.c index ee91f50..c204fdb 100644 --- a/source/gx/fileio/unzip.c +++ b/source/gx/fileio/unzip.c @@ -108,7 +108,7 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename) int bufferoffset = 0; int have = 0; char readbuffer[2048]; - char msg[128]; + char msg[64]; FILE *fatfile = NULL; /*** FAT file support ***/ @@ -133,6 +133,12 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename) /*** Copy PKZip header to local, used as info ***/ memcpy (&pkzip, &readbuffer, sizeof (PKZIPHEADER)); + if (FLIP32 (pkzip.uncompressedSize) > MAXROMSIZE) + { + GUI_WaitPrompt("Error","File size not supported !"); + return 0; + } + sprintf (msg, "Unzipping %d bytes ...", FLIP32 (pkzip.uncompressedSize)); GUI_MsgBoxOpen("Information",msg,1); diff --git a/source/gx/gui/filesel.c b/source/gx/gui/filesel.c index a458e5c..cc27c6f 100644 --- a/source/gx/gui/filesel.c +++ b/source/gx/gui/filesel.c @@ -532,7 +532,11 @@ int FileSelector(unsigned char *buffer, bool useFAT) else size = DVD_LoadFile(buffer,selection); - /* Reload emulation */ + /* Exit menu */ + GUI_MsgBoxClose(); + GUI_DeleteMenu(m); + + /* Init emulation */ if (size) { if (config.s_auto & 2) @@ -544,9 +548,6 @@ int FileSelector(unsigned char *buffer, bool useFAT) slot_autoload(config.s_default,config.s_device); } - /* Exit */ - GUI_MsgBoxClose(); - GUI_DeleteMenu(m); return size; } } diff --git a/source/gx/gui/filesel.h b/source/gx/gui/filesel.h index c84b43f..0c0c5ad 100644 --- a/source/gx/gui/filesel.h +++ b/source/gx/gui/filesel.h @@ -26,7 +26,7 @@ #define _FILESEL_H #define MAXJOLIET 256 -#define MAXFILES 1000 +#define MAXFILES 500 /* Filelist structure */ typedef struct diff --git a/source/gx/gui/font.c b/source/gx/gui/font.c index 2b5c05b..ec2b085 100644 --- a/source/gx/gui/font.c +++ b/source/gx/gui/font.c @@ -36,7 +36,7 @@ typedef struct _yay0header { unsigned int chunks_offset ATTRIBUTE_PACKED; } yay0header; -int font_size[256]; +u8 font_size[256]; int fheight; static u8 *fontImage; @@ -265,7 +265,7 @@ int FONT_Init(void) else c = i - fontHeader->first_char; - font_size[i] = ((unsigned char*)fontHeader)[fontHeader->width_table + c]; + font_size[i] = ((u8*)fontHeader)[fontHeader->width_table + c]; } /* font height */ @@ -403,7 +403,7 @@ void WriteCentre_HL( int y, char *string) * Draw functions (FrameBuffer) * ****************************************************************************/ -void fntDrawHLine (int x1, int x2, int y, int color) +static void fntDrawHLine (int x1, int x2, int y, int color) { int i; y = 320 * y; @@ -412,21 +412,6 @@ void fntDrawHLine (int x1, int x2, int y, int color) for (i = x1; i <= x2; i++) xfb[whichfb][y + i] = color; } -void fntDrawVLine (int x, int y1, int y2, int color) -{ - int i; - x >>= 1; - for (i = y1; i <= y2; i++) xfb[whichfb][x + (640 * i) / 2] = color; -} - -void fntDrawBox (int x1, int y1, int x2, int y2, int color) -{ - fntDrawHLine (x1, x2, y1, color); - fntDrawHLine (x1, x2, y2, color); - fntDrawVLine (x1, y1, y2, color); - fntDrawVLine (x2, y1, y2, color); -} - void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color) { int h; diff --git a/source/gx/gui/font.h b/source/gx/gui/font.h index 1ce6b3d..ea03f2e 100644 --- a/source/gx/gui/font.h +++ b/source/gx/gui/font.h @@ -37,6 +37,6 @@ extern void write_font (int x, int y, char *string); extern void WriteText(char *text, int size, int x, int y); extern void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color); extern int fheight; -extern int font_size[256]; +extern u8 font_size[256]; #endif diff --git a/source/gx/gui/gui.c b/source/gx/gui/gui.c index ff5fdb1..5b2010b 100644 --- a/source/gx/gui/gui.c +++ b/source/gx/gui/gui.c @@ -1710,66 +1710,47 @@ void GUI_OptionBox2(gui_menu *parent, char *text_1, char *text_2, s16 *option_1, /* Message Box displays a message until a specific action is completed */ /* Message Box LWP Thread */ -static void *MsgBox_Thread(void *arg) +static void *MsgBox_Thread(gui_message *message_box) { - while (1) + while (message_box->refresh) { - if (message_box.refresh) + /* draw parent menu */ + GUI_DrawMenu(message_box->parent); + + /* 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) { - /* draw parent menu */ - GUI_DrawMenu(message_box.parent); - - /* 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) - { - if (message_box.buttonB) - { - FONT_write("OK",18,220+message_box.buttonA->width+6,288,640,(GXColor)WHITE); - FONT_alignRight("CANCEL",18,166+message_box.window->width-(220-166),288,(GXColor)WHITE); - if (message_box.buttonA) - gxDrawTexture(message_box.buttonA, 220, 288-18+(18-message_box.buttonA->height)/2,message_box.buttonA->width, message_box.buttonA->height,255); - if (message_box.buttonB) - gxDrawTexture(message_box.buttonB, 328, 288-18+(18-message_box.buttonB->height)/2,message_box.buttonB->width, message_box.buttonB->height,255); - } - else - { - FONT_writeCenter("Press to continue.",18,166,166+message_box.window->width,248+22,(GXColor)WHITE); - if (message_box.buttonA) - 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; - } - else - { - LWP_YieldThread(); + 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 NULL; + return 0; } /* update current Message Box */ @@ -1787,12 +1768,7 @@ void GUI_MsgBoxOpen(char *title, char *msg, bool throbber) if (SILENT) return; - /* clear unused textures */ - gxTextureClose(&message_box.buttonA); - gxTextureClose(&message_box.buttonB); - gxTextureClose(&message_box.throbber); - - /* update message box */ + /* update text */ GUI_MsgBoxUpdate(title,msg); /* ensure we are not already running */ @@ -1841,20 +1817,9 @@ void GUI_MsgBoxOpen(char *title, char *msg, bool throbber) yoffset -= 60; } - /* Final position */ - GUI_DrawMenu(message_box.parent); - gxDrawTexture(message_box.window,xwindow,ywindow,message_box.window->width,message_box.window->height,230); - gxDrawTexture(message_box.top,xwindow,ywindow,message_box.top->width,message_box.top->height,255); - if (title) - FONT_writeCenter(title,20,xwindow,xwindow+message_box.window->width,ywindow+(message_box.top->height-20)/2+20,(GXColor)WHITE); - if (msg) - FONT_writeCenter(msg,18,xwindow,xwindow+message_box.window->width,ypos,(GXColor)WHITE); - gxSetScreen(); - - /* resume LWP thread for MessageBox refresh */ - message_box.progress = 0; + /* create LWP thread for MessageBox refresh */ message_box.refresh = TRUE; - LWP_ResumeThread(msgboxthread); + LWP_CreateThread (&msgboxthread, (void *)MsgBox_Thread, &message_box, NULL, 0, 70); } } @@ -1865,7 +1830,7 @@ void GUI_MsgBoxClose(void) { /* suspend MessageBox refresh */ message_box.refresh = FALSE; - LWP_SuspendThread(msgboxthread); + LWP_JoinThread(msgboxthread, NULL); /* window position */ int xwindow = 166; @@ -1912,7 +1877,6 @@ void GUI_MsgBoxClose(void) gxTextureClose(&message_box.window); gxTextureClose(&message_box.top); gxTextureClose(&message_box.buttonA); - gxTextureClose(&message_box.buttonB); gxTextureClose(&message_box.throbber); } } @@ -1922,7 +1886,10 @@ void GUI_WaitPrompt(char *title, char *msg) if (SILENT) return; - /* update message box */ + /* clear unused texture */ + gxTextureClose(&message_box.throbber); + + /* open or update message box */ GUI_MsgBoxOpen(title, msg, 0); /* allocate texture */ @@ -1968,12 +1935,3 @@ void GUI_SetBgColor(u8 color) } } -/* Initialize GUI engine */ -void GUI_Initialize(void) -{ - /* create LWP thread for MessageBox refresh */ - message_box.refresh = FALSE; - LWP_CreateThread (&msgboxthread, MsgBox_Thread, NULL, NULL, 0, 10); - LWP_SuspendThread(msgboxthread); -} - diff --git a/source/gx/gui/gui.h b/source/gx/gui/gui.h index fe8266e..2f32a66 100644 --- a/source/gx/gui/gui.h +++ b/source/gx/gui/gui.h @@ -132,7 +132,6 @@ typedef struct 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 *buttonB; /* pointer to button B texture */ gx_texture *throbber; /* pointer to throbber texture */ } gui_message; diff --git a/source/gx/gui/menu.c b/source/gx/gui/menu.c index 98e66e3..f965dd2 100644 --- a/source/gx/gui/menu.c +++ b/source/gx/gui/menu.c @@ -1046,8 +1046,8 @@ static void systemmenu () if (cart.romsize) { - /* force region & cpu mode */ - set_region(); + /* reset console region */ + region_autodetect(); /* update framerate */ if (vdp_pal) @@ -1494,7 +1494,7 @@ static void ctrlmenu_raz(void) m->buttons[i+2].data = &button_player_data; m->buttons[i+2].state |= BUTTON_ACTIVE; sprintf(m->items[i+2].text,"%d",max + 1); - if (cart.hw.jcart && (i > 4)) + if (cart.jcart && (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); @@ -1674,7 +1674,7 @@ static void ctrlmenu(void) switch (m->selected) { case 0: /* update port 1 system */ - if (cart.hw.jcart) break; + if (cart.jcart) break; if (input.system[0] == SYSTEM_MOUSE) input.system[0] +=3; /* lightguns are never used on Port 1 */ else @@ -1688,8 +1688,6 @@ static void ctrlmenu(void) input.system[0] = NO_SYSTEM; input.system[1] = SYSTEM_GAMEPAD; } - old_system[0] = -1; - old_system[1] = -1; io_init(); io_reset(); old_system[0] = input.system[0]; @@ -1729,7 +1727,7 @@ static void ctrlmenu(void) break; case 1: /* update port 2 system */ - if (cart.hw.jcart) break; + if (cart.jcart) break; input.system[1] ++; if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE)) input.system[1] ++; @@ -1740,8 +1738,6 @@ static void ctrlmenu(void) input.system[1] = NO_SYSTEM; input.system[0] = SYSTEM_GAMEPAD; } - old_system[0] = -1; - old_system[1] = -1; io_init(); io_reset(); old_system[0] = input.system[0]; @@ -1861,7 +1857,7 @@ static void ctrlmenu(void) GUI_DrawMenuFX(m, 20, 0); /* update title */ - if (cart.hw.jcart && (player > 1)) + if (cart.jcart && (player > 1)) sprintf(m->title,"Controller Settings (Player %d) (J-CART)",player+1); else sprintf(m->title,"Controller Settings (Player %d)",player+1); @@ -2112,7 +2108,7 @@ static void ctrlmenu(void) } /* remove duplicate assigned inputs before leaving */ - for (i=0; i<8; i++) + for (i=0; i 10) @@ -2699,7 +2698,8 @@ static void showcredits(void) while (!p) { gxClearScreen ((GXColor)BLACK); - gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255); + 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("original 1.2a version by Charles MacDonald", 18, 0, 640, 516 - offset, (GXColor)WHITE); @@ -2876,7 +2876,9 @@ void MainMenu (void) switch (GUI_OptionWindow(m, VERSION, items,3)) { case 0: /* credits */ + GUI_DeleteMenu(m); showcredits(); + GUI_InitMenu(m); break; case 1: /* return to loader */ diff --git a/source/gx/gx_input.c b/source/gx/gx_input.c index 2b8f764..2e462f8 100644 --- a/source/gx/gx_input.c +++ b/source/gx/gx_input.c @@ -85,7 +85,7 @@ static void pad_config(int chan, int max_keys) { int i; u16 p,key; - char msg[30]; + char msg[64]; /* reset VSYNC callback */ VIDEO_SetPostRetraceCallback(NULL); @@ -168,7 +168,9 @@ static void pad_update(s8 chan, u8 i) else if ((p & PAD_TRIGGER_L) && (p & PAD_TRIGGER_Z)) { /* Soft RESET */ - set_softreset(); + if (config.lock_on == TYPE_AR) + datel_reset(0); + gen_reset(0); } /* Retrieve current key mapping */ @@ -344,7 +346,7 @@ static s8 WPAD_StickY(WPADData *data, u8 right) static void wpad_config(u8 chan, u8 exp, u8 max_keys) { int i; - char msg[30]; + char msg[64]; u32 key,p = 255; /* remove inputs update callback */ @@ -473,7 +475,9 @@ static void wpad_update(s8 chan, u8 i, u32 exp) ((p & WPAD_CLASSIC_BUTTON_PLUS) && (p & WPAD_CLASSIC_BUTTON_MINUS))) { /* Soft RESET */ - set_softreset(); + if (config.lock_on == TYPE_AR) + datel_reset(0); + gen_reset(0); } /* Retrieve current key mapping */ @@ -610,7 +614,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp) if (system_hw != SYSTEM_PICO) { /* gamepad */ - if ((p & wpad_dirmap[exp][PAD_UP]) || (y > ANALOG_SENSITIVITY)) + 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; @@ -822,7 +826,9 @@ void gx_input_UpdateEmu(void) if (SYS_ResetButtonDown()) { /* Soft RESET */ - set_softreset(); + if (config.lock_on == TYPE_AR) + datel_reset(0); + gen_reset(0); } #endif diff --git a/source/gx/gx_video.c b/source/gx/gx_video.c index 3e5b284..f505148 100644 --- a/source/gx/gx_video.c +++ b/source/gx/gx_video.c @@ -58,10 +58,10 @@ u8 *screenshot; /* Texture Data */ u32 gc_pal = 0; /*** NTSC Filters ***/ -sms_ntsc_t sms_ntsc; -md_ntsc_t md_ntsc; -static sms_ntsc_setup_t sms_setup; -static md_ntsc_setup_t md_setup; +sms_ntsc_t *sms_ntsc; +md_ntsc_t *md_ntsc; +static const sms_ntsc_setup_t *sms_setup; +static const md_ntsc_setup_t *md_setup; /*** GX FIFO ***/ static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32); @@ -1266,6 +1266,12 @@ void gxTextureClose(gx_texture **p_texture) /* Emulation mode -> Menu mode */ void gx_video_Stop(void) { + /* unallocate NTSC filters */ + if (sms_ntsc) + free(sms_ntsc); + if (md_ntsc) + free(md_ntsc); + /* lightgun textures */ gxTextureClose(&crosshair[0]); gxTextureClose(&crosshair[1]); @@ -1274,6 +1280,10 @@ void gx_video_Stop(void) gxResetRendering(1); gxResetMode(vmode); + /* display game snapshot */ + gxClearScreen((GXColor)BLACK); + gxDrawScreenshot(0xff); + /* default VI settings */ VIDEO_SetPreRetraceCallback(NULL); VIDEO_SetPostRetraceCallback(gx_input_UpdateMenu); @@ -1282,14 +1292,12 @@ void gx_video_Stop(void) VIDEO_SetGamma(VI_GM_1_0); #endif - /* default TV mode */ + /* adjust TV width */ vmode->viWidth = config.screen_w; vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth)/2; VIDEO_Configure(vmode); - /* starts menu rendering */ - gxClearScreen((GXColor)BLACK); - gxDrawScreenshot(0xff); + /* wait for VSYNC */ gxSetScreen(); } @@ -1344,27 +1352,35 @@ void gx_video_Start(void) vwidth = bitmap.viewport.w + (2 * bitmap.viewport.x); vheight = bitmap.viewport.h + (2 * bitmap.viewport.y); - /* software NTSC filters */ - if (config.ntsc == 1) + /* NTSC filter */ + sms_ntsc = NULL; + md_ntsc = NULL; + if (config.ntsc) { - sms_setup = sms_ntsc_composite; - md_setup = md_ntsc_composite; - sms_ntsc_init( &sms_ntsc, &sms_setup ); - md_ntsc_init( &md_ntsc, &md_setup ); - } - else if (config.ntsc == 2) - { - sms_setup = sms_ntsc_svideo; - md_setup = md_ntsc_svideo; - sms_ntsc_init( &sms_ntsc, &sms_setup ); - md_ntsc_init( &md_ntsc, &md_setup ); - } - else if (config.ntsc == 3) - { - sms_setup = sms_ntsc_rgb; - md_setup = md_ntsc_rgb; - sms_ntsc_init( &sms_ntsc, &sms_setup ); - md_ntsc_init( &md_ntsc, &md_setup ); + /* allocate filters */ + sms_ntsc = (sms_ntsc_t *)memalign(32,sizeof(sms_ntsc_t)); + md_ntsc = (md_ntsc_t *)memalign(32,sizeof(md_ntsc_t)); + + /* setup filters default configuration */ + switch (config.ntsc) + { + case 1: + sms_setup = &sms_ntsc_composite; + md_setup = &md_ntsc_composite; + break; + case 2: + sms_setup = &sms_ntsc_svideo; + md_setup = &md_ntsc_svideo; + break; + case 3: + sms_setup = &sms_ntsc_rgb; + md_setup = &md_ntsc_rgb; + break; + } + + /* initialize filters */ + sms_ntsc_init(sms_ntsc, sms_setup); + md_ntsc_init(md_ntsc, md_setup); } /* lightgun textures */ diff --git a/source/gx/main.c b/source/gx/main.c index 4760382..337e129 100644 --- a/source/gx/main.c +++ b/source/gx/main.c @@ -155,6 +155,54 @@ static void init_machine(void) bitmap.data = texturemem; } +static void run_emulation(void) +{ + /* main emulation loop */ + while (1) + { + /* Main Menu request */ + if (ConfigRequested) + { + /* stop video & audio */ + gx_audio_Stop(); + gx_video_Stop(); + + /* show menu */ + MainMenu (); + ConfigRequested = 0; + + /* start video & audio */ + gx_audio_Start(); + gx_video_Start(); + frameticker = 1; + } + + /* automatic frame skipping */ + if (frameticker > 1) + { + /* skip frame */ + frameticker = 0; + system_frame(1); + } + else + { + /* render frame */ + frameticker = 0; + system_frame(0); + + /* update video */ + gx_video_Update(); + } + + /* update audio */ + gx_audio_Update(); + + /* wait for next frame */ + while (frameticker < 1) + usleep(1); + } +} + /************************************************** Load a new rom and performs some initialization ***************************************************/ @@ -325,62 +373,13 @@ int main (int argc, char *argv[]) SILENT = 0; } - /* initialize GUI engine */ - GUI_Initialize(); - #ifdef HW_RVL /* Power button callback */ SYS_SetPowerCallback(Power_Off); #endif /* main emulation loop */ - int skip = 0; - while (1) - { - /* Main Menu request */ - if (ConfigRequested) - { - /* stop video & audio */ - gx_audio_Stop(); - gx_video_Stop(); - - /* show menu */ - MainMenu (); - ConfigRequested = 0; - - /* start video & audio */ - gx_audio_Start(); - gx_video_Start(); - skip = 0; - } - - frameticker = 0; - if (skip) - { - /* skip frame */ - system_frame(1); - skip = 0; - } - else - { - /* render frame */ - system_frame(0); - - /* update video */ - gx_video_Update(); - } - - /* update audio */ - gx_audio_Update(); - - /* wait for next frame */ - while (frameticker < 1) - usleep(1); - - /* automatic frame skipping */ - if (frameticker > 1) - skip = 1; - } + run_emulation(); return 0; } diff --git a/source/loadrom.c b/source/loadrom.c index 0082903..4e035af 100644 --- a/source/loadrom.c +++ b/source/loadrom.c @@ -57,8 +57,23 @@ #define PCDROM 4096 #define PMOUSE 8192 -uint16 peripherals; -uint16 realchecksum; +#define MAXCOMPANY 64 +#define MAXPERIPHERALS 14 + + +typedef struct +{ + char companyid[6]; + char company[26]; +} COMPANYINFO; + +typedef struct +{ + char pID[2]; + char pName[14]; +} PERIPHERALINFO; + + ROMINFO rominfo; char rom_filename[256]; @@ -69,7 +84,7 @@ char rom_filename[256]; * Based on the document provided at * http://www.zophar.net/tech/files/Genesis_ROM_Format.txt **************************************************************************/ -COMPANYINFO companyinfo[MAXCOMPANY] = { +static COMPANYINFO companyinfo[MAXCOMPANY] = { {"ACLD", "Ballistic"}, {"RSI", "Razorsoft"}, {"SEGA", "SEGA"}, @@ -105,7 +120,7 @@ COMPANYINFO companyinfo[MAXCOMPANY] = { {"50", "Electronic Arts"}, {"56", "Razorsoft"}, {"58", "Mentrix"}, - {"60", "Victor Musical Industries"}, + {"60", "Victor Musical Ind."}, {"69", "Arena"}, {"70", "Virgin"}, {"73", "Soft Vision"}, @@ -142,7 +157,7 @@ COMPANYINFO companyinfo[MAXCOMPANY] = { * Based on the document provided at * http://www.zophar.net/tech/files/Genesis_ROM_Format.txt ***************************************************************************/ -PERIPHERALINFO peripheralinfo[14] = { +static PERIPHERALINFO peripheralinfo[MAXPERIPHERALS] = { {"J", "3B Joypad"}, {"6", "6B Joypad"}, {"K", "Keyboard"}, @@ -156,13 +171,14 @@ PERIPHERALINFO peripheralinfo[14] = { {"T", "Tablet"}, {"V", "Paddle"}, {"C", "CD-ROM"}, - {"M", "Mega Mouse"} + {"M", "Mega Mouse"}, }; -/* - * softdev - New Checksum Calculation - eke-eke: fixed - */ + /*************************************************************************** + * GetRealChecksum + * + * Compute ROM checksum. + ***************************************************************************/ static uint16 GetRealChecksum (uint8 *rom, int length) { int i; @@ -217,31 +233,28 @@ static void getrominfo (char *romheader) memcpy (&rominfo.ROMType, romheader + ROMTYPE, 2); memcpy (&rominfo.product, romheader + ROMPRODUCT, 12); memcpy (&rominfo.checksum, romheader + ROMCHECKSUM, 2); - memcpy (&rominfo.io_support, romheader + ROMIOSUPPORT, 16); memcpy (&rominfo.romstart, romheader + ROMROMSTART, 4); memcpy (&rominfo.romend, romheader + ROMROMEND, 4); - memcpy (&rominfo.RAMInfo, romheader + ROMRAMINFO, 12); - memcpy (&rominfo.ramstart, romheader + ROMRAMSTART, 4); - memcpy (&rominfo.ramend, romheader + ROMRAMEND, 4); - memcpy (&rominfo.modem, romheader + ROMMODEMINFO, 12); - memcpy (&rominfo.memo, romheader + ROMMEMO, 40); memcpy (&rominfo.country, romheader + ROMCOUNTRY, 16); - realchecksum = GetRealChecksum (((uint8 *) cart.rom) + 0x200, cart.romsize - 0x200); #ifdef LSB_FIRST rominfo.checksum = (rominfo.checksum >> 8) | ((rominfo.checksum & 0xff) << 8); #endif + rominfo.realchecksum = GetRealChecksum (((uint8 *) cart.rom) + 0x200, cart.romsize - 0x200); - peripherals = 0; - + rominfo.peripherals = 0; for (i = 0; i < 14; i++) - for (j=0; j < 14; j++) - if (rominfo.io_support[i] == peripheralinfo[j].pID[0]) - peripherals |= (1 << j); + for (j=0; j < 14; j++) + if (romheader[ROMIOSUPPORT+i] == peripheralinfo[j].pID[0]) + rominfo.peripherals |= (1 << j); } -/* SMD (interleaved) rom support */ -static void deinterleave_block (uint8 * src) + /*************************************************************************** + * deinterleave_block + * + * Convert interleaved (.smd) ROM files. + ***************************************************************************/ +static void deinterleave_block(uint8 * src) { int i; uint8 block[0x4000]; @@ -253,6 +266,11 @@ static void deinterleave_block (uint8 * src) } } + /*************************************************************************** + * load_rom + * + * Load a new ROM file. + ***************************************************************************/ int load_rom(char *filename) { int i, size, offset = 0; @@ -274,12 +292,8 @@ int load_rom(char *filename) { size -= 512; offset += 512; - for (i = 0; i < (size / 0x4000); i += 1) - { deinterleave_block (cart.rom + offset + (i * 0x4000)); - } - memcpy(cart.rom, cart.rom + offset, size); } @@ -288,13 +302,16 @@ int load_rom(char *filename) cart.romsize = size; /* clear unused ROM space */ - memset (cart.rom + size, 0xff, MAXROMSIZE - size); + memset(cart.rom + size, 0xff, MAXROMSIZE - size); /* get infos from ROM header */ getrominfo((char *)cart.rom); - /* set system region */ - set_region(); + /* get specific input devices */ + input_autodetect(); + + /* get default region */ + region_autodetect(); #ifdef LSB_FIRST /* Byteswap ROM */ @@ -331,8 +348,13 @@ int load_rom(char *filename) return(1); } -/* 05/05/2006: new region detection routine (taken from GENS sourcecode) */ -void set_region () +/**************************************************************************** + * region_autodetect + * + * Set console region upon ROM header + * + ****************************************************************************/ +void region_autodetect(void) { /* country codes used to differentiate region */ /* 0001 = japan ntsc (1) */ @@ -379,7 +401,7 @@ void set_region () /* need PAL settings */ region_code = REGION_EUROPE; } - else if ((realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL)) + else if ((rominfo.realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL)) { /* On Dal Jang Goon (Korea) needs JAP region code */ region_code = REGION_JAPAN_NTSC; @@ -410,7 +432,7 @@ void set_region () } /**************************************************************************** - * getcompany + * get_company * * Try to determine which company made this rom * @@ -418,13 +440,14 @@ void set_region () * It seems that there can be pretty much anything you like following the * copyright (C) symbol! ****************************************************************************/ -int getcompany () +char *get_company(void) { char *s; int i; char company[10]; - for (i = 3; i < 8; i++) company[i - 3] = rominfo.copyright[i]; + for (i = 3; i < 8; i++) + company[i - 3] = rominfo.copyright[i]; company[5] = 0; /** OK, first look for a hyphen @@ -439,14 +462,31 @@ int getcompany () /** Strip any trailing spaces **/ for (i = strlen (company) - 1; i >= 0; i--) - if (company[i] == 32) company[i] = 0; + if (company[i] == 32) + company[i] = 0; - if (strlen (company) == 0) return MAXCOMPANY - 1; + if (strlen (company) == 0) + return companyinfo[MAXCOMPANY - 1].company; for (i = 0; i < MAXCOMPANY - 1; i++) { - if (!(strncmp (company, companyinfo[i].companyid, strlen (company)))) return i; + if (!(strncmp (company, companyinfo[i].companyid, strlen (company)))) + return companyinfo[i].company; } - return MAXCOMPANY - 1; + return companyinfo[MAXCOMPANY - 1].company; } + +/**************************************************************************** + * get_peripheral + * + * Return peripheral name based on header code + * + ****************************************************************************/ +char *get_peripheral(int index) +{ + if (index < MAXPERIPHERALS) + return peripheralinfo[index].pName; + return companyinfo[MAXCOMPANY - 1].company; +} + diff --git a/source/loadrom.h b/source/loadrom.h index 9bf26c5..e1f89a1 100644 --- a/source/loadrom.h +++ b/source/loadrom.h @@ -23,53 +23,34 @@ #ifndef _LOADROM_H_ #define _LOADROM_H_ -#define MAXCOMPANY 64 #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]; /* Educational or Game */ - char product[14]; /* Product serial number */ - unsigned short checksum; /* Checksum */ - char io_support[18]; /* Actually 16 chars :) */ - unsigned int romstart; /* ROM start address */ - unsigned int romend; /* ROM end address */ - char RAMInfo[14]; /* Backup RAM header */ - unsigned int ramstart; /* RAM start address */ - unsigned int ramend; /* RAM end address */ - char modem[14]; /* Sega Modem support */ - char memo[50]; /* Misc */ - char country[18]; /* Country flag */ + 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]; /* Educational or Game */ + 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; -typedef struct -{ - char companyid[6]; - char company[30]; -} COMPANYINFO; - -typedef struct -{ - char pID[2]; - char pName[21]; -} PERIPHERALINFO; /* Global variables */ extern ROMINFO rominfo; -extern COMPANYINFO companyinfo[MAXCOMPANY]; -extern PERIPHERALINFO peripheralinfo[14]; -extern uint16 realchecksum; -extern uint16 peripherals; extern char rom_filename[256]; /* Function prototypes */ extern int load_rom(char *filename); -extern int getcompany(); -extern void set_region(); +extern void region_autodetect(void); +extern char *get_company(void); +extern char *get_peripheral(int index); #endif /* _LOADROM_H_ */ diff --git a/source/m68k/m68kcpu.c b/source/m68k/m68kcpu.c index 2b3462e..0a9f411 100644 --- a/source/m68k/m68kcpu.c +++ b/source/m68k/m68kcpu.c @@ -124,7 +124,7 @@ const uint m68ki_shift_32_table[65] = /* Number of clock cycles to use for exception processing. * I used 4 for any vectors that are undocumented for processing times. */ -uint16 m68ki_exception_cycle_table[4][256] = +uint16 m68ki_exception_cycle_table[NUM_CPU_TYPES][256] = { { /* 000 */ 40, /* 0: Reset - Initial Stack Pointer */ @@ -199,6 +199,8 @@ uint16 m68ki_exception_cycle_table[4][256] = 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 }, + +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 { /* 010 */ 40, /* 0: Reset - Initial Stack Pointer */ 4, /* 1: Reset - Initial Program Counter */ @@ -418,6 +420,7 @@ uint16 m68ki_exception_cycle_table[4][256] = 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 } +#endif }; #if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 @@ -694,6 +697,8 @@ void m68k_set_cpu_type(unsigned int cpu_type) CYC_SHIFT = 2 * 7; CYC_RESET = 132 * 7; return; + +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 case M68K_CPU_TYPE_68008: CPU_TYPE = CPU_TYPE_008; CPU_ADDRESS_MASK = 0x003fffff; @@ -774,6 +779,7 @@ void m68k_set_cpu_type(unsigned int cpu_type) CYC_SHIFT = 0; CYC_RESET = 518; return; +#endif } } diff --git a/source/m68k/m68kops.c b/source/m68k/m68kops.c index 7225699..899443e 100644 --- a/source/m68k/m68kops.c +++ b/source/m68k/m68kops.c @@ -21,6 +21,7 @@ static void m68k_op_1111(void) } +#if M68K_EMULATE_040 static void m68k_op_040fpu0_32(void) { if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) @@ -41,7 +42,7 @@ static void m68k_op_040fpu1_32(void) } m68ki_exception_1111(); } - +#endif static void m68k_op_abcd_8_rr(void) { @@ -5255,6 +5256,7 @@ static void m68k_op_bclr_8_s_al(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_bfchg_32_d(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -8051,8 +8053,10 @@ static void m68k_op_bftst_32_pcix(void) } m68ki_exception_illegal(); } +#endif +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_bkpt(void) { if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) @@ -8061,6 +8065,7 @@ static void m68k_op_bkpt(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_bra_8(void) @@ -8529,6 +8534,7 @@ static void m68k_op_btst_8_s_pcix(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_callm_32_ai(void) { /* note: watch out for pcrelative modes */ @@ -9417,6 +9423,7 @@ static void m68k_op_cas2_32(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_chk_16_d(void) @@ -9617,6 +9624,7 @@ static void m68k_op_chk_16_i(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_chk_32_d(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -10552,6 +10560,7 @@ static void m68k_op_chk2cmp2_32_al(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_clr_8_d(void) @@ -11763,6 +11772,7 @@ static void m68k_op_cmpi_8_al(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_cmpi_8_pcdi(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -11797,6 +11807,7 @@ static void m68k_op_cmpi_8_pcix(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_cmpi_16_d(void) @@ -11903,6 +11914,7 @@ static void m68k_op_cmpi_16_al(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_cmpi_16_pcdi(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -11937,6 +11949,7 @@ static void m68k_op_cmpi_16_pcix(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_cmpi_32_d(void) @@ -12045,6 +12058,7 @@ static void m68k_op_cmpi_32_al(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_cmpi_32_pcdi(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -12079,6 +12093,7 @@ static void m68k_op_cmpi_32_pcix(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_cmpm_8_ax7(void) @@ -12159,6 +12174,7 @@ static void m68k_op_cmpm_32(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_cpbcc_32(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -12222,6 +12238,7 @@ static void m68k_op_cptrapcc_32(void) } m68ki_exception_1111(); } +#endif static void m68k_op_dbt_16(void) @@ -13381,6 +13398,7 @@ static void m68k_op_divu_16_i(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_divl_32_d(void) { #if M68K_USE_64_BIT @@ -15700,6 +15718,7 @@ static void m68k_op_divl_32_i(void) #endif } +#endif static void m68k_op_eor_8_d(void) @@ -16510,6 +16529,7 @@ static void m68k_op_ext_32(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_extb_32(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -16526,6 +16546,7 @@ static void m68k_op_extb_32(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_illegal(void) @@ -16713,6 +16734,7 @@ static void m68k_op_link_16(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_link_32_a7(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -16739,6 +16761,7 @@ static void m68k_op_link_32(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_lsr_8_s(void) @@ -21949,6 +21972,7 @@ static void m68k_op_movea_32_i(void) } +#if M68K_EMULATE_010 ||M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_move_16_frc_d(void) { if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) @@ -22035,6 +22059,7 @@ static void m68k_op_move_16_frc_al(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_move_16_toc_d(void) @@ -22362,6 +22387,7 @@ static void m68k_op_move_32_tou(void) } +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_movec_32_cr(void) { if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) @@ -22640,6 +22666,7 @@ static void m68k_op_movec_32_rc(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_movem_16_re_pd(void) @@ -23219,6 +23246,7 @@ static void m68k_op_movep_32_er(void) } +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_moves_8_ai(void) { if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) @@ -23987,6 +24015,7 @@ static void m68k_op_moves_32_al(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_moveq_32(void) @@ -24412,6 +24441,7 @@ static void m68k_op_mulu_16_i(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_mull_32_d(void) { #if M68K_USE_64_BIT @@ -25774,6 +25804,7 @@ static void m68k_op_mull_32_i(void) #endif } +#endif static void m68k_op_nbcd_8_d(void) @@ -28404,6 +28435,7 @@ static void m68k_op_ori_16_tos(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_pack_16_rr(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -28484,6 +28516,7 @@ static void m68k_op_pack_16_mm(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_pea_32_ai(void) @@ -28542,6 +28575,7 @@ static void m68k_op_pea_32_pcix(void) } +#if M68K_EMULATE_040 static void m68k_op_pflush_32(void) { if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) @@ -28551,6 +28585,7 @@ static void m68k_op_pflush_32(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_reset(void) @@ -29723,6 +29758,7 @@ static void m68k_op_roxl_16_al(void) } +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_rtd_32(void) { if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) @@ -29736,6 +29772,7 @@ static void m68k_op_rtd_32(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_rte_32(void) @@ -29824,6 +29861,7 @@ rte_loop: } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_rtm_32(void) { if(CPU_TYPE_IS_020_VARIANT(CPU_TYPE)) @@ -29836,7 +29874,7 @@ static void m68k_op_rtm_32(void) } m68ki_exception_illegal(); } - +#endif static void m68k_op_rtr_32(void) { @@ -33476,6 +33514,7 @@ static void m68k_op_trap(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_trapt(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -34155,6 +34194,7 @@ static void m68k_op_traple_32(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_trapv(void) @@ -34277,6 +34317,7 @@ static void m68k_op_tst_8_al(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_tst_8_pcdi(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -34323,6 +34364,7 @@ static void m68k_op_tst_8_i(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_tst_16_d(void) @@ -34336,6 +34378,7 @@ static void m68k_op_tst_16_d(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_tst_16_a(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -34350,6 +34393,7 @@ static void m68k_op_tst_16_a(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_tst_16_ai(void) @@ -34429,6 +34473,7 @@ static void m68k_op_tst_16_al(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_tst_16_pcdi(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -34475,6 +34520,7 @@ static void m68k_op_tst_16_i(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_tst_32_d(void) @@ -34488,6 +34534,7 @@ static void m68k_op_tst_32_d(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_tst_32_a(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -34502,6 +34549,7 @@ static void m68k_op_tst_32_a(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_tst_32_ai(void) @@ -34581,6 +34629,7 @@ static void m68k_op_tst_32_al(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_tst_32_pcdi(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -34627,6 +34676,7 @@ static void m68k_op_tst_32_i(void) } m68ki_exception_illegal(); } +#endif static void m68k_op_unlk_32_a7(void) @@ -34644,6 +34694,7 @@ static void m68k_op_unlk_32(void) } +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 static void m68k_op_unpk_16_rr(void) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) @@ -34732,6 +34783,7 @@ static void m68k_op_unpk_16_mm(void) } m68ki_exception_illegal(); } +#endif /* ======================================================================== */ @@ -34745,8 +34797,6 @@ static void m68k_op_unpk_16_mm(void) #include "m68kops.h" -#define NUM_CPU_TYPES 4 - void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */ unsigned char m68ki_cycles[NUM_CPU_TYPES][0x10000]; /* Cycles used by CPU type */ @@ -34756,7 +34806,7 @@ 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[NUM_CPU_TYPES]; /* cycles each cpu type takes */ + unsigned char cycles[4]; /* cycles each cpu type takes */ } opcode_handler_struct; @@ -34769,9 +34819,11 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_1010 , 0xf000, 0xa000, { 4, 4, 4, 4}}, {m68k_op_1111 , 0xf000, 0xf000, { 4, 4, 4, 4}}, {m68k_op_moveq_32 , 0xf100, 0x7000, { 4, 4, 2, 2}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_cpbcc_32 , 0xf180, 0xf080, { 0, 0, 4, 0}}, {m68k_op_cpgen_32 , 0xf1c0, 0xf000, { 0, 0, 4, 0}}, {m68k_op_cpscc_32 , 0xf1c0, 0xf040, { 0, 0, 4, 0}}, +#endif {m68k_op_bra_8 , 0xff00, 0x6000, { 10, 10, 10, 10}}, {m68k_op_bsr_8 , 0xff00, 0x6100, { 18, 18, 7, 7}}, {m68k_op_bhi_8 , 0xff00, 0x6200, { 10, 10, 6, 6}}, @@ -34788,8 +34840,10 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_blt_8 , 0xff00, 0x6d00, { 10, 10, 6, 6}}, {m68k_op_bgt_8 , 0xff00, 0x6e00, { 10, 10, 6, 6}}, {m68k_op_ble_8 , 0xff00, 0x6f00, { 10, 10, 6, 6}}, +#if M68K_EMULATE_040 {m68k_op_040fpu0_32 , 0xff00, 0xf200, { 0, 0, 0, 0}}, {m68k_op_040fpu1_32 , 0xff00, 0xf300, { 0, 0, 0, 0}}, +#endif {m68k_op_btst_32_r_d , 0xf1f8, 0x0100, { 6, 6, 4, 4}}, {m68k_op_movep_16_er , 0xf1f8, 0x0108, { 16, 16, 12, 12}}, {m68k_op_btst_8_r_ai , 0xf1f8, 0x0110, { 8, 8, 8, 8}}, @@ -34952,12 +35006,14 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_move_16_ix_pd , 0xf1f8, 0x31a0, { 20, 20, 12, 12}}, {m68k_op_move_16_ix_di , 0xf1f8, 0x31a8, { 22, 22, 12, 12}}, {m68k_op_move_16_ix_ix , 0xf1f8, 0x31b0, { 24, 24, 14, 14}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_chk_32_d , 0xf1f8, 0x4100, { 0, 0, 8, 8}}, {m68k_op_chk_32_ai , 0xf1f8, 0x4110, { 0, 0, 12, 12}}, {m68k_op_chk_32_pi , 0xf1f8, 0x4118, { 0, 0, 12, 12}}, {m68k_op_chk_32_pd , 0xf1f8, 0x4120, { 0, 0, 13, 13}}, {m68k_op_chk_32_di , 0xf1f8, 0x4128, { 0, 0, 13, 13}}, {m68k_op_chk_32_ix , 0xf1f8, 0x4130, { 0, 0, 15, 15}}, +#endif {m68k_op_chk_16_d , 0xf1f8, 0x4180, { 10, 8, 8, 8}}, {m68k_op_chk_16_ai , 0xf1f8, 0x4190, { 14, 12, 12, 12}}, {m68k_op_chk_16_pi , 0xf1f8, 0x4198, { 14, 12, 12, 12}}, @@ -35038,15 +35094,19 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_or_8_re_pd , 0xf1f8, 0x8120, { 14, 14, 9, 9}}, {m68k_op_or_8_re_di , 0xf1f8, 0x8128, { 16, 16, 9, 9}}, {m68k_op_or_8_re_ix , 0xf1f8, 0x8130, { 18, 18, 11, 11}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_pack_16_rr , 0xf1f8, 0x8140, { 0, 0, 6, 6}}, {m68k_op_pack_16_mm , 0xf1f8, 0x8148, { 0, 0, 13, 13}}, +#endif {m68k_op_or_16_re_ai , 0xf1f8, 0x8150, { 12, 12, 8, 8}}, {m68k_op_or_16_re_pi , 0xf1f8, 0x8158, { 12, 12, 8, 8}}, {m68k_op_or_16_re_pd , 0xf1f8, 0x8160, { 14, 14, 9, 9}}, {m68k_op_or_16_re_di , 0xf1f8, 0x8168, { 16, 16, 9, 9}}, {m68k_op_or_16_re_ix , 0xf1f8, 0x8170, { 18, 18, 11, 11}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_unpk_16_rr , 0xf1f8, 0x8180, { 0, 0, 8, 8}}, {m68k_op_unpk_16_mm , 0xf1f8, 0x8188, { 0, 0, 13, 13}}, +#endif {m68k_op_or_32_re_ai , 0xf1f8, 0x8190, { 20, 20, 8, 8}}, {m68k_op_or_32_re_pi , 0xf1f8, 0x8198, { 20, 20, 8, 8}}, {m68k_op_or_32_re_pd , 0xf1f8, 0x81a0, { 22, 22, 9, 9}}, @@ -35321,9 +35381,11 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_lsl_32_r , 0xf1f8, 0xe1a8, { 8, 8, 6, 6}}, {m68k_op_roxl_32_r , 0xf1f8, 0xe1b0, { 8, 8, 12, 12}}, {m68k_op_rol_32_r , 0xf1f8, 0xe1b8, { 8, 8, 8, 8}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_cpdbcc_32 , 0xf1f8, 0xf048, { 0, 0, 4, 0}}, {m68k_op_cptrapcc_32 , 0xf1f8, 0xf078, { 0, 0, 4, 0}}, {m68k_op_rtm_32 , 0xfff0, 0x06c0, { 0, 0, 19, 19}}, +#endif {m68k_op_trap , 0xfff0, 0x4e40, { 4, 4, 4, 4}}, {m68k_op_btst_8_r_pi7 , 0xf1ff, 0x011f, { 8, 8, 8, 8}}, {m68k_op_btst_8_r_pd7 , 0xf1ff, 0x0127, { 10, 10, 9, 9}}, @@ -35456,11 +35518,13 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_move_16_ix_pcdi , 0xf1ff, 0x31ba, { 22, 22, 12, 12}}, {m68k_op_move_16_ix_pcix , 0xf1ff, 0x31bb, { 24, 24, 14, 14}}, {m68k_op_move_16_ix_i , 0xf1ff, 0x31bc, { 18, 18, 9, 9}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_chk_32_aw , 0xf1ff, 0x4138, { 0, 0, 12, 12}}, {m68k_op_chk_32_al , 0xf1ff, 0x4139, { 0, 0, 12, 12}}, {m68k_op_chk_32_pcdi , 0xf1ff, 0x413a, { 0, 0, 13, 13}}, {m68k_op_chk_32_pcix , 0xf1ff, 0x413b, { 0, 0, 15, 15}}, {m68k_op_chk_32_i , 0xf1ff, 0x413c, { 0, 0, 12, 12}}, +#endif {m68k_op_chk_16_aw , 0xf1ff, 0x41b8, { 18, 16, 12, 12}}, {m68k_op_chk_16_al , 0xf1ff, 0x41b9, { 22, 20, 12, 12}}, {m68k_op_chk_16_pcdi , 0xf1ff, 0x41ba, { 18, 16, 13, 13}}, @@ -35513,10 +35577,14 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_or_8_re_pd7 , 0xf1ff, 0x8127, { 14, 14, 9, 9}}, {m68k_op_or_8_re_aw , 0xf1ff, 0x8138, { 16, 16, 8, 8}}, {m68k_op_or_8_re_al , 0xf1ff, 0x8139, { 20, 20, 8, 8}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_pack_16_mm_ay7 , 0xf1ff, 0x814f, { 0, 0, 13, 13}}, +#endif {m68k_op_or_16_re_aw , 0xf1ff, 0x8178, { 16, 16, 8, 8}}, {m68k_op_or_16_re_al , 0xf1ff, 0x8179, { 20, 20, 8, 8}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_unpk_16_mm_ay7 , 0xf1ff, 0x818f, { 0, 0, 13, 13}}, +#endif {m68k_op_or_32_re_aw , 0xf1ff, 0x81b8, { 24, 24, 8, 8}}, {m68k_op_or_32_re_al , 0xf1ff, 0x81b9, { 28, 28, 8, 8}}, {m68k_op_divs_16_aw , 0xf1ff, 0x81f8, { 8, 130, 60, 60}}, @@ -35686,9 +35754,11 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_ori_32_pd , 0xfff8, 0x00a0, { 30, 30, 9, 9}}, {m68k_op_ori_32_di , 0xfff8, 0x00a8, { 32, 32, 9, 9}}, {m68k_op_ori_32_ix , 0xfff8, 0x00b0, { 34, 34, 11, 11}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_chk2cmp2_8_ai , 0xfff8, 0x00d0, { 0, 0, 22, 22}}, {m68k_op_chk2cmp2_8_di , 0xfff8, 0x00e8, { 0, 0, 23, 23}}, {m68k_op_chk2cmp2_8_ix , 0xfff8, 0x00f0, { 0, 0, 25, 25}}, +#endif {m68k_op_andi_8_d , 0xfff8, 0x0200, { 8, 8, 2, 2}}, {m68k_op_andi_8_ai , 0xfff8, 0x0210, { 16, 16, 8, 8}}, {m68k_op_andi_8_pi , 0xfff8, 0x0218, { 16, 16, 8, 8}}, @@ -35707,9 +35777,11 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_andi_32_pd , 0xfff8, 0x02a0, { 30, 30, 9, 9}}, {m68k_op_andi_32_di , 0xfff8, 0x02a8, { 32, 32, 9, 9}}, {m68k_op_andi_32_ix , 0xfff8, 0x02b0, { 34, 34, 11, 11}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_chk2cmp2_16_ai , 0xfff8, 0x02d0, { 0, 0, 22, 22}}, {m68k_op_chk2cmp2_16_di , 0xfff8, 0x02e8, { 0, 0, 23, 23}}, {m68k_op_chk2cmp2_16_ix , 0xfff8, 0x02f0, { 0, 0, 25, 25}}, +#endif {m68k_op_subi_8_d , 0xfff8, 0x0400, { 8, 8, 2, 2}}, {m68k_op_subi_8_ai , 0xfff8, 0x0410, { 16, 16, 8, 8}}, {m68k_op_subi_8_pi , 0xfff8, 0x0418, { 16, 16, 8, 8}}, @@ -35728,9 +35800,11 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_subi_32_pd , 0xfff8, 0x04a0, { 30, 30, 9, 9}}, {m68k_op_subi_32_di , 0xfff8, 0x04a8, { 32, 32, 9, 9}}, {m68k_op_subi_32_ix , 0xfff8, 0x04b0, { 34, 34, 11, 11}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_chk2cmp2_32_ai , 0xfff8, 0x04d0, { 0, 0, 22, 22}}, {m68k_op_chk2cmp2_32_di , 0xfff8, 0x04e8, { 0, 0, 23, 23}}, {m68k_op_chk2cmp2_32_ix , 0xfff8, 0x04f0, { 0, 0, 25, 25}}, +#endif {m68k_op_addi_8_d , 0xfff8, 0x0600, { 8, 8, 2, 2}}, {m68k_op_addi_8_ai , 0xfff8, 0x0610, { 16, 16, 8, 8}}, {m68k_op_addi_8_pi , 0xfff8, 0x0618, { 16, 16, 8, 8}}, @@ -35749,9 +35823,11 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_addi_32_pd , 0xfff8, 0x06a0, { 30, 30, 9, 9}}, {m68k_op_addi_32_di , 0xfff8, 0x06a8, { 32, 32, 9, 9}}, {m68k_op_addi_32_ix , 0xfff8, 0x06b0, { 34, 34, 11, 11}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_callm_32_ai , 0xfff8, 0x06d0, { 0, 0, 64, 64}}, {m68k_op_callm_32_di , 0xfff8, 0x06e8, { 0, 0, 65, 65}}, {m68k_op_callm_32_ix , 0xfff8, 0x06f0, { 0, 0, 67, 67}}, +#endif {m68k_op_btst_32_s_d , 0xfff8, 0x0800, { 10, 10, 4, 4}}, {m68k_op_btst_8_s_ai , 0xfff8, 0x0810, { 12, 12, 8, 8}}, {m68k_op_btst_8_s_pi , 0xfff8, 0x0818, { 12, 12, 8, 8}}, @@ -35794,11 +35870,13 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_eori_32_pd , 0xfff8, 0x0aa0, { 30, 30, 9, 9}}, {m68k_op_eori_32_di , 0xfff8, 0x0aa8, { 32, 32, 9, 9}}, {m68k_op_eori_32_ix , 0xfff8, 0x0ab0, { 34, 34, 11, 11}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_cas_8_ai , 0xfff8, 0x0ad0, { 0, 0, 16, 16}}, {m68k_op_cas_8_pi , 0xfff8, 0x0ad8, { 0, 0, 16, 16}}, {m68k_op_cas_8_pd , 0xfff8, 0x0ae0, { 0, 0, 17, 17}}, {m68k_op_cas_8_di , 0xfff8, 0x0ae8, { 0, 0, 17, 17}}, {m68k_op_cas_8_ix , 0xfff8, 0x0af0, { 0, 0, 19, 19}}, +#endif {m68k_op_cmpi_8_d , 0xfff8, 0x0c00, { 8, 8, 2, 2}}, {m68k_op_cmpi_8_ai , 0xfff8, 0x0c10, { 12, 12, 6, 6}}, {m68k_op_cmpi_8_pi , 0xfff8, 0x0c18, { 12, 12, 6, 6}}, @@ -35817,11 +35895,14 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_cmpi_32_pd , 0xfff8, 0x0ca0, { 22, 22, 7, 7}}, {m68k_op_cmpi_32_di , 0xfff8, 0x0ca8, { 24, 24, 7, 7}}, {m68k_op_cmpi_32_ix , 0xfff8, 0x0cb0, { 26, 26, 9, 9}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_cas_16_ai , 0xfff8, 0x0cd0, { 0, 0, 16, 16}}, {m68k_op_cas_16_pi , 0xfff8, 0x0cd8, { 0, 0, 16, 16}}, {m68k_op_cas_16_pd , 0xfff8, 0x0ce0, { 0, 0, 17, 17}}, {m68k_op_cas_16_di , 0xfff8, 0x0ce8, { 0, 0, 17, 17}}, {m68k_op_cas_16_ix , 0xfff8, 0x0cf0, { 0, 0, 19, 19}}, +#endif +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_moves_8_ai , 0xfff8, 0x0e10, { 0, 18, 9, 9}}, {m68k_op_moves_8_pi , 0xfff8, 0x0e18, { 0, 18, 9, 9}}, {m68k_op_moves_8_pd , 0xfff8, 0x0e20, { 0, 20, 10, 10}}, @@ -35837,11 +35918,14 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_moves_32_pd , 0xfff8, 0x0ea0, { 0, 28, 10, 10}}, {m68k_op_moves_32_di , 0xfff8, 0x0ea8, { 0, 32, 10, 10}}, {m68k_op_moves_32_ix , 0xfff8, 0x0eb0, { 0, 36, 12, 12}}, +#endif +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_cas_32_ai , 0xfff8, 0x0ed0, { 0, 0, 16, 16}}, {m68k_op_cas_32_pi , 0xfff8, 0x0ed8, { 0, 0, 16, 16}}, {m68k_op_cas_32_pd , 0xfff8, 0x0ee0, { 0, 0, 17, 17}}, {m68k_op_cas_32_di , 0xfff8, 0x0ee8, { 0, 0, 17, 17}}, {m68k_op_cas_32_ix , 0xfff8, 0x0ef0, { 0, 0, 19, 19}}, +#endif {m68k_op_move_8_aw_d , 0xfff8, 0x11c0, { 12, 12, 4, 4}}, {m68k_op_move_8_aw_ai , 0xfff8, 0x11d0, { 16, 16, 8, 8}}, {m68k_op_move_8_aw_pi , 0xfff8, 0x11d8, { 16, 16, 8, 8}}, @@ -35936,12 +36020,14 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_clr_32_pd , 0xfff8, 0x42a0, { 22, 14, 9, 9}}, {m68k_op_clr_32_di , 0xfff8, 0x42a8, { 24, 16, 9, 9}}, {m68k_op_clr_32_ix , 0xfff8, 0x42b0, { 26, 20, 11, 11}}, +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_move_16_frc_d , 0xfff8, 0x42c0, { 0, 4, 4, 4}}, {m68k_op_move_16_frc_ai , 0xfff8, 0x42d0, { 0, 12, 8, 8}}, {m68k_op_move_16_frc_pi , 0xfff8, 0x42d8, { 0, 12, 8, 8}}, {m68k_op_move_16_frc_pd , 0xfff8, 0x42e0, { 0, 14, 9, 9}}, {m68k_op_move_16_frc_di , 0xfff8, 0x42e8, { 0, 16, 9, 9}}, {m68k_op_move_16_frc_ix , 0xfff8, 0x42f0, { 0, 18, 11, 11}}, +#endif {m68k_op_neg_8_d , 0xfff8, 0x4400, { 4, 4, 2, 2}}, {m68k_op_neg_8_ai , 0xfff8, 0x4410, { 12, 12, 8, 8}}, {m68k_op_neg_8_pi , 0xfff8, 0x4418, { 12, 12, 8, 8}}, @@ -35991,14 +36077,18 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_move_16_tos_di , 0xfff8, 0x46e8, { 20, 20, 13, 13}}, {m68k_op_move_16_tos_ix , 0xfff8, 0x46f0, { 22, 22, 15, 15}}, {m68k_op_nbcd_8_d , 0xfff8, 0x4800, { 6, 6, 6, 6}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_link_32 , 0xfff8, 0x4808, { 0, 0, 6, 6}}, +#endif {m68k_op_nbcd_8_ai , 0xfff8, 0x4810, { 12, 12, 10, 10}}, {m68k_op_nbcd_8_pi , 0xfff8, 0x4818, { 12, 12, 10, 10}}, {m68k_op_nbcd_8_pd , 0xfff8, 0x4820, { 14, 14, 11, 11}}, {m68k_op_nbcd_8_di , 0xfff8, 0x4828, { 16, 16, 11, 11}}, {m68k_op_nbcd_8_ix , 0xfff8, 0x4830, { 18, 18, 13, 13}}, {m68k_op_swap_32 , 0xfff8, 0x4840, { 4, 4, 4, 4}}, +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_bkpt , 0xfff8, 0x4848, { 0, 10, 10, 10}}, +#endif {m68k_op_pea_32_ai , 0xfff8, 0x4850, { 12, 12, 9, 9}}, {m68k_op_pea_32_di , 0xfff8, 0x4868, { 16, 16, 10, 10}}, {m68k_op_pea_32_ix , 0xfff8, 0x4870, { 20, 20, 12, 12}}, @@ -36012,7 +36102,9 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_movem_32_re_pd , 0xfff8, 0x48e0, { 8, 8, 4, 4}}, {m68k_op_movem_32_re_di , 0xfff8, 0x48e8, { 12, 12, 9, 9}}, {m68k_op_movem_32_re_ix , 0xfff8, 0x48f0, { 14, 14, 11, 11}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_extb_32 , 0xfff8, 0x49c0, { 0, 0, 4, 4}}, +#endif {m68k_op_tst_8_d , 0xfff8, 0x4a00, { 4, 4, 2, 2}}, {m68k_op_tst_8_ai , 0xfff8, 0x4a10, { 8, 8, 6, 6}}, {m68k_op_tst_8_pi , 0xfff8, 0x4a18, { 8, 8, 6, 6}}, @@ -36020,14 +36112,18 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_tst_8_di , 0xfff8, 0x4a28, { 12, 12, 7, 7}}, {m68k_op_tst_8_ix , 0xfff8, 0x4a30, { 14, 14, 9, 9}}, {m68k_op_tst_16_d , 0xfff8, 0x4a40, { 4, 4, 2, 2}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_tst_16_a , 0xfff8, 0x4a48, { 0, 0, 2, 2}}, +#endif {m68k_op_tst_16_ai , 0xfff8, 0x4a50, { 8, 8, 6, 6}}, {m68k_op_tst_16_pi , 0xfff8, 0x4a58, { 8, 8, 6, 6}}, {m68k_op_tst_16_pd , 0xfff8, 0x4a60, { 10, 10, 7, 7}}, {m68k_op_tst_16_di , 0xfff8, 0x4a68, { 12, 12, 7, 7}}, {m68k_op_tst_16_ix , 0xfff8, 0x4a70, { 14, 14, 9, 9}}, {m68k_op_tst_32_d , 0xfff8, 0x4a80, { 4, 4, 2, 2}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_tst_32_a , 0xfff8, 0x4a88, { 0, 0, 2, 2}}, +#endif {m68k_op_tst_32_ai , 0xfff8, 0x4a90, { 12, 12, 6, 6}}, {m68k_op_tst_32_pi , 0xfff8, 0x4a98, { 12, 12, 6, 6}}, {m68k_op_tst_32_pd , 0xfff8, 0x4aa0, { 14, 14, 7, 7}}, @@ -36039,6 +36135,7 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_tas_8_pd , 0xfff8, 0x4ae0, { 20, 20, 17, 17}}, {m68k_op_tas_8_di , 0xfff8, 0x4ae8, { 22, 22, 17, 17}}, {m68k_op_tas_8_ix , 0xfff8, 0x4af0, { 24, 24, 19, 19}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_mull_32_d , 0xfff8, 0x4c00, { 0, 0, 43, 43}}, {m68k_op_mull_32_ai , 0xfff8, 0x4c10, { 0, 0, 47, 47}}, {m68k_op_mull_32_pi , 0xfff8, 0x4c18, { 0, 0, 47, 47}}, @@ -36051,6 +36148,7 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_divl_32_pd , 0xfff8, 0x4c60, { 0, 0, 89, 89}}, {m68k_op_divl_32_di , 0xfff8, 0x4c68, { 0, 0, 89, 89}}, {m68k_op_divl_32_ix , 0xfff8, 0x4c70, { 0, 0, 91, 91}}, +#endif {m68k_op_movem_16_er_ai , 0xfff8, 0x4c90, { 12, 12, 12, 12}}, {m68k_op_movem_16_er_pi , 0xfff8, 0x4c98, { 12, 12, 8, 8}}, {m68k_op_movem_16_er_di , 0xfff8, 0x4ca8, { 16, 16, 13, 13}}, @@ -36182,8 +36280,10 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_sle_8_di , 0xfff8, 0x5fe8, { 16, 16, 11, 11}}, {m68k_op_sle_8_ix , 0xfff8, 0x5ff0, { 18, 18, 13, 13}}, {m68k_op_sbcd_8_mm_ax7 , 0xfff8, 0x8f08, { 18, 18, 16, 16}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_pack_16_mm_ax7 , 0xfff8, 0x8f48, { 0, 0, 13, 13}}, {m68k_op_unpk_16_mm_ax7 , 0xfff8, 0x8f88, { 0, 0, 13, 13}}, +#endif {m68k_op_subx_8_mm_ax7 , 0xfff8, 0x9f08, { 18, 18, 12, 12}}, {m68k_op_cmpm_8_ax7 , 0xfff8, 0xbf08, { 12, 12, 9, 9}}, {m68k_op_abcd_8_mm_ax7 , 0xfff8, 0xcf08, { 18, 18, 16, 16}}, @@ -36228,6 +36328,7 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_rol_16_pd , 0xfff8, 0xe7e0, { 14, 14, 12, 12}}, {m68k_op_rol_16_di , 0xfff8, 0xe7e8, { 16, 16, 12, 12}}, {m68k_op_rol_16_ix , 0xfff8, 0xe7f0, { 18, 18, 14, 14}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_bftst_32_d , 0xfff8, 0xe8c0, { 0, 0, 6, 6}}, {m68k_op_bftst_32_ai , 0xfff8, 0xe8d0, { 0, 0, 17, 17}}, {m68k_op_bftst_32_di , 0xfff8, 0xe8e8, { 0, 0, 18, 18}}, @@ -36260,7 +36361,8 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_bfins_32_ai , 0xfff8, 0xefd0, { 0, 0, 21, 21}}, {m68k_op_bfins_32_di , 0xfff8, 0xefe8, { 0, 0, 22, 22}}, {m68k_op_bfins_32_ix , 0xfff8, 0xeff0, { 0, 0, 24, 24}}, - {m68k_op_move16_32 , 0xfff8, 0xf620, { 0, 0, 0, 4}}, +#endif + {m68k_op_move16_32 , 0xfff8, 0xf620, { 0, 0, 0, 4}}, /* ???????? */ {m68k_op_ori_8_pi7 , 0xffff, 0x001f, { 16, 16, 8, 8}}, {m68k_op_ori_8_pd7 , 0xffff, 0x0027, { 18, 18, 9, 9}}, {m68k_op_ori_8_aw , 0xffff, 0x0038, { 20, 20, 8, 8}}, @@ -36271,10 +36373,12 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_ori_16_tos , 0xffff, 0x007c, { 20, 16, 12, 12}}, {m68k_op_ori_32_aw , 0xffff, 0x00b8, { 32, 32, 8, 8}}, {m68k_op_ori_32_al , 0xffff, 0x00b9, { 36, 36, 8, 8}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_chk2cmp2_8_aw , 0xffff, 0x00f8, { 0, 0, 22, 22}}, {m68k_op_chk2cmp2_8_al , 0xffff, 0x00f9, { 0, 0, 22, 22}}, {m68k_op_chk2cmp2_8_pcdi , 0xffff, 0x00fa, { 0, 0, 23, 23}}, {m68k_op_chk2cmp2_8_pcix , 0xffff, 0x00fb, { 0, 0, 23, 23}}, +#endif {m68k_op_andi_8_pi7 , 0xffff, 0x021f, { 16, 16, 8, 8}}, {m68k_op_andi_8_pd7 , 0xffff, 0x0227, { 18, 18, 9, 9}}, {m68k_op_andi_8_aw , 0xffff, 0x0238, { 20, 20, 8, 8}}, @@ -36285,10 +36389,12 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_andi_16_tos , 0xffff, 0x027c, { 20, 16, 12, 12}}, {m68k_op_andi_32_aw , 0xffff, 0x02b8, { 32, 32, 8, 8}}, {m68k_op_andi_32_al , 0xffff, 0x02b9, { 36, 36, 8, 8}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_chk2cmp2_16_aw , 0xffff, 0x02f8, { 0, 0, 22, 22}}, {m68k_op_chk2cmp2_16_al , 0xffff, 0x02f9, { 0, 0, 22, 22}}, {m68k_op_chk2cmp2_16_pcdi , 0xffff, 0x02fa, { 0, 0, 23, 23}}, {m68k_op_chk2cmp2_16_pcix , 0xffff, 0x02fb, { 0, 0, 23, 23}}, +#endif {m68k_op_subi_8_pi7 , 0xffff, 0x041f, { 16, 16, 8, 8}}, {m68k_op_subi_8_pd7 , 0xffff, 0x0427, { 18, 18, 9, 9}}, {m68k_op_subi_8_aw , 0xffff, 0x0438, { 20, 20, 8, 8}}, @@ -36297,10 +36403,12 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_subi_16_al , 0xffff, 0x0479, { 24, 24, 8, 8}}, {m68k_op_subi_32_aw , 0xffff, 0x04b8, { 32, 32, 8, 8}}, {m68k_op_subi_32_al , 0xffff, 0x04b9, { 36, 36, 8, 8}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_chk2cmp2_32_aw , 0xffff, 0x04f8, { 0, 0, 22, 22}}, {m68k_op_chk2cmp2_32_al , 0xffff, 0x04f9, { 0, 0, 22, 22}}, {m68k_op_chk2cmp2_32_pcdi , 0xffff, 0x04fa, { 0, 0, 23, 23}}, {m68k_op_chk2cmp2_32_pcix , 0xffff, 0x04fb, { 0, 0, 23, 23}}, +#endif {m68k_op_addi_8_pi7 , 0xffff, 0x061f, { 16, 16, 8, 8}}, {m68k_op_addi_8_pd7 , 0xffff, 0x0627, { 18, 18, 9, 9}}, {m68k_op_addi_8_aw , 0xffff, 0x0638, { 20, 20, 8, 8}}, @@ -36309,10 +36417,12 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_addi_16_al , 0xffff, 0x0679, { 24, 24, 8, 8}}, {m68k_op_addi_32_aw , 0xffff, 0x06b8, { 32, 32, 8, 8}}, {m68k_op_addi_32_al , 0xffff, 0x06b9, { 36, 36, 8, 8}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_callm_32_aw , 0xffff, 0x06f8, { 0, 0, 64, 64}}, {m68k_op_callm_32_al , 0xffff, 0x06f9, { 0, 0, 64, 64}}, {m68k_op_callm_32_pcdi , 0xffff, 0x06fa, { 0, 0, 65, 65}}, {m68k_op_callm_32_pcix , 0xffff, 0x06fb, { 0, 0, 67, 67}}, +#endif {m68k_op_btst_8_s_pi7 , 0xffff, 0x081f, { 12, 12, 8, 8}}, {m68k_op_btst_8_s_pd7 , 0xffff, 0x0827, { 14, 14, 9, 9}}, {m68k_op_btst_8_s_aw , 0xffff, 0x0838, { 16, 16, 8, 8}}, @@ -36341,27 +36451,36 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_eori_16_tos , 0xffff, 0x0a7c, { 20, 16, 12, 12}}, {m68k_op_eori_32_aw , 0xffff, 0x0ab8, { 32, 32, 8, 8}}, {m68k_op_eori_32_al , 0xffff, 0x0ab9, { 36, 36, 8, 8}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_cas_8_pi7 , 0xffff, 0x0adf, { 0, 0, 16, 16}}, {m68k_op_cas_8_pd7 , 0xffff, 0x0ae7, { 0, 0, 17, 17}}, {m68k_op_cas_8_aw , 0xffff, 0x0af8, { 0, 0, 16, 16}}, {m68k_op_cas_8_al , 0xffff, 0x0af9, { 0, 0, 16, 16}}, +#endif {m68k_op_cmpi_8_pi7 , 0xffff, 0x0c1f, { 12, 12, 6, 6}}, {m68k_op_cmpi_8_pd7 , 0xffff, 0x0c27, { 14, 14, 7, 7}}, {m68k_op_cmpi_8_aw , 0xffff, 0x0c38, { 16, 16, 6, 6}}, {m68k_op_cmpi_8_al , 0xffff, 0x0c39, { 20, 20, 6, 6}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_cmpi_8_pcdi , 0xffff, 0x0c3a, { 0, 0, 7, 7}}, {m68k_op_cmpi_8_pcix , 0xffff, 0x0c3b, { 0, 0, 9, 9}}, +#endif {m68k_op_cmpi_16_aw , 0xffff, 0x0c78, { 16, 16, 6, 6}}, {m68k_op_cmpi_16_al , 0xffff, 0x0c79, { 20, 20, 6, 6}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_cmpi_16_pcdi , 0xffff, 0x0c7a, { 0, 0, 7, 7}}, {m68k_op_cmpi_16_pcix , 0xffff, 0x0c7b, { 0, 0, 9, 9}}, +#endif {m68k_op_cmpi_32_aw , 0xffff, 0x0cb8, { 24, 24, 6, 6}}, {m68k_op_cmpi_32_al , 0xffff, 0x0cb9, { 28, 28, 6, 6}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_cmpi_32_pcdi , 0xffff, 0x0cba, { 0, 0, 7, 7}}, {m68k_op_cmpi_32_pcix , 0xffff, 0x0cbb, { 0, 0, 9, 9}}, {m68k_op_cas_16_aw , 0xffff, 0x0cf8, { 0, 0, 16, 16}}, {m68k_op_cas_16_al , 0xffff, 0x0cf9, { 0, 0, 16, 16}}, {m68k_op_cas2_16 , 0xffff, 0x0cfc, { 0, 0, 12, 12}}, +#endif +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_moves_8_pi7 , 0xffff, 0x0e1f, { 0, 18, 9, 9}}, {m68k_op_moves_8_pd7 , 0xffff, 0x0e27, { 0, 20, 10, 10}}, {m68k_op_moves_8_aw , 0xffff, 0x0e38, { 0, 26, 9, 9}}, @@ -36370,9 +36489,12 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_moves_16_al , 0xffff, 0x0e79, { 0, 30, 9, 9}}, {m68k_op_moves_32_aw , 0xffff, 0x0eb8, { 0, 32, 9, 9}}, {m68k_op_moves_32_al , 0xffff, 0x0eb9, { 0, 36, 9, 9}}, +#endif +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_cas_32_aw , 0xffff, 0x0ef8, { 0, 0, 16, 16}}, {m68k_op_cas_32_al , 0xffff, 0x0ef9, { 0, 0, 16, 16}}, {m68k_op_cas2_32 , 0xffff, 0x0efc, { 0, 0, 12, 12}}, +#endif {m68k_op_move_8_aw_pi7 , 0xffff, 0x11df, { 16, 16, 8, 8}}, {m68k_op_move_8_aw_pd7 , 0xffff, 0x11e7, { 18, 18, 9, 9}}, {m68k_op_move_8_aw_aw , 0xffff, 0x11f8, { 20, 20, 8, 8}}, @@ -36439,8 +36561,10 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_clr_16_al , 0xffff, 0x4279, { 20, 14, 8, 8}}, {m68k_op_clr_32_aw , 0xffff, 0x42b8, { 24, 16, 8, 8}}, {m68k_op_clr_32_al , 0xffff, 0x42b9, { 28, 20, 8, 8}}, +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_move_16_frc_aw , 0xffff, 0x42f8, { 0, 16, 8, 8}}, {m68k_op_move_16_frc_al , 0xffff, 0x42f9, { 0, 20, 8, 8}}, +#endif {m68k_op_neg_8_pi7 , 0xffff, 0x441f, { 12, 12, 8, 8}}, {m68k_op_neg_8_pd7 , 0xffff, 0x4427, { 14, 14, 9, 9}}, {m68k_op_neg_8_aw , 0xffff, 0x4438, { 16, 16, 8, 8}}, @@ -36467,7 +36591,9 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_move_16_tos_pcdi , 0xffff, 0x46fa, { 20, 20, 13, 13}}, {m68k_op_move_16_tos_pcix , 0xffff, 0x46fb, { 22, 22, 15, 15}}, {m68k_op_move_16_tos_i , 0xffff, 0x46fc, { 16, 16, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_link_32_a7 , 0xffff, 0x480f, { 0, 0, 6, 6}}, +#endif {m68k_op_nbcd_8_pi7 , 0xffff, 0x481f, { 12, 12, 10, 10}}, {m68k_op_nbcd_8_pd7 , 0xffff, 0x4827, { 14, 14, 11, 11}}, {m68k_op_nbcd_8_aw , 0xffff, 0x4838, { 16, 16, 10, 10}}, @@ -36484,24 +36610,31 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_tst_8_pd7 , 0xffff, 0x4a27, { 10, 10, 7, 7}}, {m68k_op_tst_8_aw , 0xffff, 0x4a38, { 12, 12, 6, 6}}, {m68k_op_tst_8_al , 0xffff, 0x4a39, { 16, 16, 6, 6}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_tst_8_pcdi , 0xffff, 0x4a3a, { 0, 0, 7, 7}}, {m68k_op_tst_8_pcix , 0xffff, 0x4a3b, { 0, 0, 9, 9}}, {m68k_op_tst_8_i , 0xffff, 0x4a3c, { 0, 0, 6, 6}}, +#endif {m68k_op_tst_16_aw , 0xffff, 0x4a78, { 12, 12, 6, 6}}, {m68k_op_tst_16_al , 0xffff, 0x4a79, { 16, 16, 6, 6}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_tst_16_pcdi , 0xffff, 0x4a7a, { 0, 0, 7, 7}}, {m68k_op_tst_16_pcix , 0xffff, 0x4a7b, { 0, 0, 9, 9}}, {m68k_op_tst_16_i , 0xffff, 0x4a7c, { 0, 0, 6, 6}}, +#endif {m68k_op_tst_32_aw , 0xffff, 0x4ab8, { 16, 16, 6, 6}}, {m68k_op_tst_32_al , 0xffff, 0x4ab9, { 20, 20, 6, 6}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_tst_32_pcdi , 0xffff, 0x4aba, { 0, 0, 7, 7}}, {m68k_op_tst_32_pcix , 0xffff, 0x4abb, { 0, 0, 9, 9}}, {m68k_op_tst_32_i , 0xffff, 0x4abc, { 0, 0, 6, 6}}, +#endif {m68k_op_tas_8_pi7 , 0xffff, 0x4adf, { 18, 18, 16, 16}}, {m68k_op_tas_8_pd7 , 0xffff, 0x4ae7, { 20, 20, 17, 17}}, {m68k_op_tas_8_aw , 0xffff, 0x4af8, { 22, 22, 16, 16}}, {m68k_op_tas_8_al , 0xffff, 0x4af9, { 26, 26, 16, 16}}, {m68k_op_illegal , 0xffff, 0x4afc, { 4, 4, 4, 4}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_mull_32_aw , 0xffff, 0x4c38, { 0, 0, 47, 47}}, {m68k_op_mull_32_al , 0xffff, 0x4c39, { 0, 0, 47, 47}}, {m68k_op_mull_32_pcdi , 0xffff, 0x4c3a, { 0, 0, 48, 48}}, @@ -36512,6 +36645,7 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_divl_32_pcdi , 0xffff, 0x4c7a, { 0, 0, 89, 89}}, {m68k_op_divl_32_pcix , 0xffff, 0x4c7b, { 0, 0, 91, 91}}, {m68k_op_divl_32_i , 0xffff, 0x4c7c, { 0, 0, 88, 88}}, +#endif {m68k_op_movem_16_er_aw , 0xffff, 0x4cb8, { 16, 16, 12, 12}}, {m68k_op_movem_16_er_al , 0xffff, 0x4cb9, { 20, 20, 12, 12}}, {m68k_op_movem_16_er_pcdi , 0xffff, 0x4cba, { 16, 16, 9, 9}}, @@ -36526,12 +36660,16 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_nop , 0xffff, 0x4e71, { 4, 4, 2, 2}}, {m68k_op_stop , 0xffff, 0x4e72, { 4, 4, 8, 8}}, {m68k_op_rte_32 , 0xffff, 0x4e73, { 20, 24, 20, 20}}, +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_rtd_32 , 0xffff, 0x4e74, { 0, 16, 10, 10}}, +#endif {m68k_op_rts_32 , 0xffff, 0x4e75, { 16, 16, 10, 10}}, {m68k_op_trapv , 0xffff, 0x4e76, { 4, 4, 4, 4}}, {m68k_op_rtr_32 , 0xffff, 0x4e77, { 20, 20, 14, 14}}, +#if M68K_EMULATE_010 || M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_movec_32_cr , 0xffff, 0x4e7a, { 0, 12, 6, 6}}, {m68k_op_movec_32_rc , 0xffff, 0x4e7b, { 0, 10, 12, 12}}, +#endif {m68k_op_jsr_32_aw , 0xffff, 0x4eb8, { 18, 18, 4, 4}}, {m68k_op_jsr_32_al , 0xffff, 0x4eb9, { 20, 20, 4, 4}}, {m68k_op_jsr_32_pcdi , 0xffff, 0x4eba, { 18, 18, 5, 5}}, @@ -36544,114 +36682,146 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_st_8_pd7 , 0xffff, 0x50e7, { 14, 14, 11, 11}}, {m68k_op_st_8_aw , 0xffff, 0x50f8, { 16, 16, 10, 10}}, {m68k_op_st_8_al , 0xffff, 0x50f9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapt_16 , 0xffff, 0x50fa, { 0, 0, 6, 6}}, {m68k_op_trapt_32 , 0xffff, 0x50fb, { 0, 0, 8, 8}}, {m68k_op_trapt , 0xffff, 0x50fc, { 0, 0, 4, 4}}, +#endif {m68k_op_sf_8_pi7 , 0xffff, 0x51df, { 12, 12, 10, 10}}, {m68k_op_sf_8_pd7 , 0xffff, 0x51e7, { 14, 14, 11, 11}}, {m68k_op_sf_8_aw , 0xffff, 0x51f8, { 16, 16, 10, 10}}, {m68k_op_sf_8_al , 0xffff, 0x51f9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapf_16 , 0xffff, 0x51fa, { 0, 0, 6, 6}}, {m68k_op_trapf_32 , 0xffff, 0x51fb, { 0, 0, 8, 8}}, {m68k_op_trapf , 0xffff, 0x51fc, { 0, 0, 4, 4}}, +#endif {m68k_op_shi_8_pi7 , 0xffff, 0x52df, { 12, 12, 10, 10}}, {m68k_op_shi_8_pd7 , 0xffff, 0x52e7, { 14, 14, 11, 11}}, {m68k_op_shi_8_aw , 0xffff, 0x52f8, { 16, 16, 10, 10}}, {m68k_op_shi_8_al , 0xffff, 0x52f9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_traphi_16 , 0xffff, 0x52fa, { 0, 0, 6, 6}}, {m68k_op_traphi_32 , 0xffff, 0x52fb, { 0, 0, 8, 8}}, {m68k_op_traphi , 0xffff, 0x52fc, { 0, 0, 4, 4}}, +#endif {m68k_op_sls_8_pi7 , 0xffff, 0x53df, { 12, 12, 10, 10}}, {m68k_op_sls_8_pd7 , 0xffff, 0x53e7, { 14, 14, 11, 11}}, {m68k_op_sls_8_aw , 0xffff, 0x53f8, { 16, 16, 10, 10}}, {m68k_op_sls_8_al , 0xffff, 0x53f9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapls_16 , 0xffff, 0x53fa, { 0, 0, 6, 6}}, {m68k_op_trapls_32 , 0xffff, 0x53fb, { 0, 0, 8, 8}}, {m68k_op_trapls , 0xffff, 0x53fc, { 0, 0, 4, 4}}, +#endif {m68k_op_scc_8_pi7 , 0xffff, 0x54df, { 12, 12, 10, 10}}, {m68k_op_scc_8_pd7 , 0xffff, 0x54e7, { 14, 14, 11, 11}}, {m68k_op_scc_8_aw , 0xffff, 0x54f8, { 16, 16, 10, 10}}, {m68k_op_scc_8_al , 0xffff, 0x54f9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapcc_16 , 0xffff, 0x54fa, { 0, 0, 6, 6}}, {m68k_op_trapcc_32 , 0xffff, 0x54fb, { 0, 0, 8, 8}}, {m68k_op_trapcc , 0xffff, 0x54fc, { 0, 0, 4, 4}}, +#endif {m68k_op_scs_8_pi7 , 0xffff, 0x55df, { 12, 12, 10, 10}}, {m68k_op_scs_8_pd7 , 0xffff, 0x55e7, { 14, 14, 11, 11}}, {m68k_op_scs_8_aw , 0xffff, 0x55f8, { 16, 16, 10, 10}}, {m68k_op_scs_8_al , 0xffff, 0x55f9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapcs_16 , 0xffff, 0x55fa, { 0, 0, 6, 6}}, {m68k_op_trapcs_32 , 0xffff, 0x55fb, { 0, 0, 8, 8}}, {m68k_op_trapcs , 0xffff, 0x55fc, { 0, 0, 4, 4}}, +#endif {m68k_op_sne_8_pi7 , 0xffff, 0x56df, { 12, 12, 10, 10}}, {m68k_op_sne_8_pd7 , 0xffff, 0x56e7, { 14, 14, 11, 11}}, {m68k_op_sne_8_aw , 0xffff, 0x56f8, { 16, 16, 10, 10}}, {m68k_op_sne_8_al , 0xffff, 0x56f9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapne_16 , 0xffff, 0x56fa, { 0, 0, 6, 6}}, {m68k_op_trapne_32 , 0xffff, 0x56fb, { 0, 0, 8, 8}}, {m68k_op_trapne , 0xffff, 0x56fc, { 0, 0, 4, 4}}, +#endif {m68k_op_seq_8_pi7 , 0xffff, 0x57df, { 12, 12, 10, 10}}, {m68k_op_seq_8_pd7 , 0xffff, 0x57e7, { 14, 14, 11, 11}}, {m68k_op_seq_8_aw , 0xffff, 0x57f8, { 16, 16, 10, 10}}, {m68k_op_seq_8_al , 0xffff, 0x57f9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapeq_16 , 0xffff, 0x57fa, { 0, 0, 6, 6}}, {m68k_op_trapeq_32 , 0xffff, 0x57fb, { 0, 0, 8, 8}}, {m68k_op_trapeq , 0xffff, 0x57fc, { 0, 0, 4, 4}}, +#endif {m68k_op_svc_8_pi7 , 0xffff, 0x58df, { 12, 12, 10, 10}}, {m68k_op_svc_8_pd7 , 0xffff, 0x58e7, { 14, 14, 11, 11}}, {m68k_op_svc_8_aw , 0xffff, 0x58f8, { 16, 16, 10, 10}}, {m68k_op_svc_8_al , 0xffff, 0x58f9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapvc_16 , 0xffff, 0x58fa, { 0, 0, 6, 6}}, {m68k_op_trapvc_32 , 0xffff, 0x58fb, { 0, 0, 8, 8}}, {m68k_op_trapvc , 0xffff, 0x58fc, { 0, 0, 4, 4}}, +#endif {m68k_op_svs_8_pi7 , 0xffff, 0x59df, { 12, 12, 10, 10}}, {m68k_op_svs_8_pd7 , 0xffff, 0x59e7, { 14, 14, 11, 11}}, {m68k_op_svs_8_aw , 0xffff, 0x59f8, { 16, 16, 10, 10}}, {m68k_op_svs_8_al , 0xffff, 0x59f9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapvs_16 , 0xffff, 0x59fa, { 0, 0, 6, 6}}, {m68k_op_trapvs_32 , 0xffff, 0x59fb, { 0, 0, 8, 8}}, {m68k_op_trapvs , 0xffff, 0x59fc, { 0, 0, 4, 4}}, +#endif {m68k_op_spl_8_pi7 , 0xffff, 0x5adf, { 12, 12, 10, 10}}, {m68k_op_spl_8_pd7 , 0xffff, 0x5ae7, { 14, 14, 11, 11}}, {m68k_op_spl_8_aw , 0xffff, 0x5af8, { 16, 16, 10, 10}}, {m68k_op_spl_8_al , 0xffff, 0x5af9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trappl_16 , 0xffff, 0x5afa, { 0, 0, 6, 6}}, {m68k_op_trappl_32 , 0xffff, 0x5afb, { 0, 0, 8, 8}}, {m68k_op_trappl , 0xffff, 0x5afc, { 0, 0, 4, 4}}, +#endif {m68k_op_smi_8_pi7 , 0xffff, 0x5bdf, { 12, 12, 10, 10}}, {m68k_op_smi_8_pd7 , 0xffff, 0x5be7, { 14, 14, 11, 11}}, {m68k_op_smi_8_aw , 0xffff, 0x5bf8, { 16, 16, 10, 10}}, {m68k_op_smi_8_al , 0xffff, 0x5bf9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapmi_16 , 0xffff, 0x5bfa, { 0, 0, 6, 6}}, {m68k_op_trapmi_32 , 0xffff, 0x5bfb, { 0, 0, 8, 8}}, {m68k_op_trapmi , 0xffff, 0x5bfc, { 0, 0, 4, 4}}, +#endif {m68k_op_sge_8_pi7 , 0xffff, 0x5cdf, { 12, 12, 10, 10}}, {m68k_op_sge_8_pd7 , 0xffff, 0x5ce7, { 14, 14, 11, 11}}, {m68k_op_sge_8_aw , 0xffff, 0x5cf8, { 16, 16, 10, 10}}, {m68k_op_sge_8_al , 0xffff, 0x5cf9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapge_16 , 0xffff, 0x5cfa, { 0, 0, 6, 6}}, {m68k_op_trapge_32 , 0xffff, 0x5cfb, { 0, 0, 8, 8}}, {m68k_op_trapge , 0xffff, 0x5cfc, { 0, 0, 4, 4}}, +#endif {m68k_op_slt_8_pi7 , 0xffff, 0x5ddf, { 12, 12, 10, 10}}, {m68k_op_slt_8_pd7 , 0xffff, 0x5de7, { 14, 14, 11, 11}}, {m68k_op_slt_8_aw , 0xffff, 0x5df8, { 16, 16, 10, 10}}, {m68k_op_slt_8_al , 0xffff, 0x5df9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_traplt_16 , 0xffff, 0x5dfa, { 0, 0, 6, 6}}, {m68k_op_traplt_32 , 0xffff, 0x5dfb, { 0, 0, 8, 8}}, {m68k_op_traplt , 0xffff, 0x5dfc, { 0, 0, 4, 4}}, +#endif {m68k_op_sgt_8_pi7 , 0xffff, 0x5edf, { 12, 12, 10, 10}}, {m68k_op_sgt_8_pd7 , 0xffff, 0x5ee7, { 14, 14, 11, 11}}, {m68k_op_sgt_8_aw , 0xffff, 0x5ef8, { 16, 16, 10, 10}}, {m68k_op_sgt_8_al , 0xffff, 0x5ef9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_trapgt_16 , 0xffff, 0x5efa, { 0, 0, 6, 6}}, {m68k_op_trapgt_32 , 0xffff, 0x5efb, { 0, 0, 8, 8}}, {m68k_op_trapgt , 0xffff, 0x5efc, { 0, 0, 4, 4}}, +#endif {m68k_op_sle_8_pi7 , 0xffff, 0x5fdf, { 12, 12, 10, 10}}, {m68k_op_sle_8_pd7 , 0xffff, 0x5fe7, { 14, 14, 11, 11}}, {m68k_op_sle_8_aw , 0xffff, 0x5ff8, { 16, 16, 10, 10}}, {m68k_op_sle_8_al , 0xffff, 0x5ff9, { 20, 20, 10, 10}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_traple_16 , 0xffff, 0x5ffa, { 0, 0, 6, 6}}, {m68k_op_traple_32 , 0xffff, 0x5ffb, { 0, 0, 8, 8}}, {m68k_op_traple , 0xffff, 0x5ffc, { 0, 0, 4, 4}}, +#endif {m68k_op_bra_16 , 0xffff, 0x6000, { 10, 10, 10, 10}}, {m68k_op_bra_32 , 0xffff, 0x60ff, { 10, 10, 10, 10}}, {m68k_op_bsr_16 , 0xffff, 0x6100, { 18, 18, 7, 7}}, @@ -36685,8 +36855,10 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_ble_16 , 0xffff, 0x6f00, { 10, 10, 6, 6}}, {m68k_op_ble_32 , 0xffff, 0x6fff, { 10, 10, 6, 6}}, {m68k_op_sbcd_8_mm_axy7 , 0xffff, 0x8f0f, { 18, 18, 16, 16}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_pack_16_mm_axy7 , 0xffff, 0x8f4f, { 0, 0, 13, 13}}, {m68k_op_unpk_16_mm_axy7 , 0xffff, 0x8f8f, { 0, 0, 13, 13}}, +#endif {m68k_op_subx_8_mm_axy7 , 0xffff, 0x9f0f, { 18, 18, 12, 12}}, {m68k_op_cmpm_8_axy7 , 0xffff, 0xbf0f, { 12, 12, 9, 9}}, {m68k_op_abcd_8_mm_axy7 , 0xffff, 0xcf0f, { 18, 18, 16, 16}}, @@ -36707,6 +36879,7 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_ror_16_al , 0xffff, 0xe6f9, { 20, 20, 11, 11}}, {m68k_op_rol_16_aw , 0xffff, 0xe7f8, { 16, 16, 11, 11}}, {m68k_op_rol_16_al , 0xffff, 0xe7f9, { 20, 20, 11, 11}}, +#if M68K_EMULATE_020 || M68K_EMULATE_EC020 || M68K_EMULATE_040 {m68k_op_bftst_32_aw , 0xffff, 0xe8f8, { 0, 0, 17, 17}}, {m68k_op_bftst_32_al , 0xffff, 0xe8f9, { 0, 0, 17, 17}}, {m68k_op_bftst_32_pcdi , 0xffff, 0xe8fa, { 0, 0, 18, 18}}, @@ -36731,7 +36904,10 @@ static const opcode_handler_struct m68k_opcode_handler_table[] = {m68k_op_bfset_32_al , 0xffff, 0xeef9, { 0, 0, 24, 24}}, {m68k_op_bfins_32_aw , 0xffff, 0xeff8, { 0, 0, 21, 21}}, {m68k_op_bfins_32_al , 0xffff, 0xeff9, { 0, 0, 21, 21}}, +#endif +#if M68K_EMULATE_040 {m68k_op_pflush_32 , 0xffff, 0xf518, { 0, 0, 0, 4}}, +#endif {0, 0, 0, {0, 0, 0, 0}} }; @@ -36746,12 +36922,8 @@ void m68ki_build_opcode_table(void) int k; for(i = 0; i < 256; i++) - { - m68ki_exception_cycle_table[0][i] = m68ki_exception_cycle_table[0][i] * 7; - m68ki_exception_cycle_table[1][i] = m68ki_exception_cycle_table[1][i] * 7; - m68ki_exception_cycle_table[2][i] = m68ki_exception_cycle_table[2][i] * 7; - m68ki_exception_cycle_table[3][i] = m68ki_exception_cycle_table[3][i] * 7; - } + for(k=0;k